2016-04-04 8 views
0

I hat die folgende Struktur:Haskell schaffen neuen Operator und Steuerfehler

Terra [[ '0', '1', '0', '1'] [ '0', '1', '0', '1'] [ '1', '0', 'G', '1']]

und de Funktion:

esTerra:: Taulell -> (Int,Int) -> Bool 
esTerra t (u,d) = 
    case t!!!u!!!d of 
     Left e -> False 
     Right p -> True 


(!!!) :: [a] -> Int -> Either Bool a 
xs !!! n | n < 0 = Left False -- error Exception: Prelude.!!:... 
[] !!! _ = Left False   -- error Exception: Prelude.!!:... 
(x:_) !!! 0 = Right x 
(_:xs) !!! n = xs!!!(n-1) 

die Funktion !!! ist gleich der Vorgang !! aber wenn Sie eine Fehlermeldung zurück gibt False zurück

aber Return-Fehler:

Couldn't match expected type ‘[a0]’ 
      with actual type ‘Either Bool [Char]’ 
In the first argument of ‘(!!!)’, namely ‘t !!! u’ 
In the expression: t !!! u !!! d 
In the expression: 
    case t !!! u !!! d of { 
    Left e -> False 
    Right p -> True } 

Weil?

Dankten

+3

auf einer Randnotiz - Ihr 'Entweder Bool a' verwendet niemals' Left True', also ist das äquivalent zur Verwendung eines 'Maybe a', wenn Ihre Wahl ein' Entweder' ist, würde ich 'Entweder String' empfehlen und mit 'Left' für 'Left" nette beschreibende Fehlermeldung "' – epsilonhalbe

Antwort

2

Ich weiß nicht, was Taulell ist, lassen Sie uns Taulell = [[a]] für einige a erraten.

Wir haben

t :: [[a]] -- Taulell 
u :: Int 
d :: Int 

daher

t !!! u :: Either Bool [a] 

Dann schreiben wir

(t !!! u) !!! d 

aber hier das äußerste linke Argument ist keine Liste, es ist ein Either Bool [a]. Daher tritt ein Typfehler auf.

Stattdessen könnten wir versuchen, z.B.

case t !!! u of 
    Left b -> ... 
    Right l -> case l !!! d of 
       Left c -> ... 
       Rigth w -> ... 
+0

okay, ich verstehe. es ist Schritt für Schritt zu machen. Vielen Dank – Merche

+2

@MercedesCabreraTorres: Sie sollten _understand_ wissen, wie es Schritt für Schritt gemacht wird, aber das ist nicht, wie Sie es in einem großen Projekt tun würden. Wenn es eine Verschachtelung von nicht zwei, aber sagen wir mal acht möglichen, fehlgeschlagenen Berechnungen gibt, dann wäre es sehr umständlich, wenn man jedem einen eigenen "Fall" gibt. Glücklicherweise nimmt die Monadeninstanz diese Last von uns! – leftaroundabout

1

!!! benötigt eine Liste als sein linkes Argument, aber für eine verschachtelte Liste ist es nicht einer einfache Liste als Ergebnis geben. Es ergibt sich ein Either Bool [a] als Ergebnis.

Sie nicht wieder als Argument für !!! verwenden können, aber man kann leicht genug anwenden!!! zur Either -contained Liste:

esTerra:: Taulell -> (Int,Int) -> Bool 
esTerra t (u,d) = 
    case t!!!u >>= (!!!d) of 
     Left e -> False 
     Right p -> True 

Hier habe ich den monadischen Operator bind verwendet >>=, um zwei möglicherweise fehlschlagende Lookups zu einem zu kombinieren, was nur gelingen wird, wenn beide Lookups tun. Dies entspricht zweimal, wobei die Either Struktur mit einem case Konstrukt, as shown by chi, explizit ausgepackt wird.

+0

dann >> = entspricht Links b -> ... Rechts l -> Fall l !!!d von .... nein? danke – Merche

+0

Ja, in diesem Fall ist es gleichwertig. Aber die monadische Bindung ist viel allgemeiner, sie funktioniert auch für Typen, die ganz anders sind als "Entweder"! – leftaroundabout

Verwandte Themen