2017-12-04 5 views
-3

Ich bin ziemlich neu in Haskell und nicht vollständig verstehen, die vielleicht Monaden.Extrahieren aus einer Liste in Haskell

Ich möchte meine Liste durch Ersetzen von Nothing mit einem Punkt und Just n mit n (alle in einer Zeile) extrahieren. Dieser Code gibt mir jedoch einen Fehler.

Couldn't match expected type "Hmm" with actual type '[Maybe a0]' 

In the pattern : [Nothing] 
In a case alternative: [Nothing] -> putStr "." 
In the expression: 
    case yd of 
    [Just val] -> putStr val 
    [Nothing] -> putStr "." 

Grundsätzlich möchte ich die Liste oben im Format sein „85.2.2 ..“

+0

Nun, welcher Fehler? –

+0

Und was für Code? –

+0

Sie sollten den Fehler immer in Ihre Frage aufnehmen, wenn Sie einen bekommen. –

Antwort

2

Die Fehlermeldung die Fehler sagt:

Couldn't match expected type "Hmm" with actual type '[Maybe a0]'

Lasst uns durch [Int] Verwendung vereinfachen statt von [Maybe Int] so können wir hier Monaden komplett aus dem Bild nehmen. Lassen Sie uns neu schreiben Sie Ihre Testfälle durch 0 statt Nothing verwenden und x statt Just x von

data Hmm = Hmm [Int] 
deriving (Show, Eq) 

yd = Hmm [8, 5, 0, 2, 0, 2, 0, 0] 

getVal = case yd of 
    [0] -> putStr "." 
    [x] -> putStr $ show x 
-- N.B. I had to reverse the order here since `[x]` will match before `[0]`. 
-- This isn't an issue when you're still using Maybes, since Just x doesn't match Nothing 

Jetzt haben wir keine monadische Elemente überhaupt bekam (außer getVal :: Hmm -> IO(), aber ...) und Sie werden nach wie vor habe das gleiche Problem wie zuvor. yd als Hmm aufgebaut, aber das einzige, Pattern-Matching Sie es tun für eine [a] sucht. Darüber hinaus suchen beide Muster nur nach einzelnen Elementlisten, sodass sie nicht übereinstimmen würden, selbst wenn yd :: [Int].

Lassen Sie sich wieder schreibt das Hmm Konstruktor in unserer Mustererkennung verwenden und Rekursion korrekt die gesamte Liste zu erfassen. Wir werden auch getVal neu schreiben die String so zurück wir, dass putStr :: String -> IO() kehrt nicht einmal mit dem IO Monade zu verwirren haben.

import Data.Char (intToDigit) 

data Hmm = Hmm [Int] 
    deriving (Show, Eq) 

yd = Hmm [8, 5, 0, 2, 0, 2, 0, 0] 

getVal :: Hmm -> String 
getVal (Hmm []) = [] 
getVal (Hmm (0:xs) = '.'   : getVal (Hmm xs) 
getVal (Hmm (x:xs) = intToDigit x : getVal (Hmm xs) 

result :: String 
result = getVal yd 

Beachten Sie, wie ich drei Änderungen in meine Muster übereinstimmt. Eine für Hmm [] - eine leere Liste, eingepackt in einen Hmm Typ, eine für Hmm (0:xs) - eine nicht leere Liste, umhüllt von einer Hmm, deren erster Wert Null ist, und eine für Hmm (x:xs) - eine nicht leere Liste, umhüllt von einer Hmm, und jedes Ergebnis, aber das erste ist rekursiv. Dies wird zurück:

getVal yd = 
getVal (Hmm (8:[5, 0, 2, 0, 2, 0, 0])) = 
'8' : getVal (Hmm (5: [0, 2, 0, 2, 0, 0])) = 
'8':'5' : getVal (Hmm (0: [2, 0, 2, 0, 0])) = 
'8':'5':'.' : getVal (Hmm (2: [0, 2, 0, 0])) = 
'8':'5':'.':'2' : getVal (Hmm (0: [2, 0, 0])) = 
'8':'5':'.':'2':'.' : getVal (Hmm (2: [0, 0])) = 
'8':'5':'.':'2':'.':'2' : getVal (Hmm (0: [0])) = 
'8':'5':'.':'2':'.':'2':'.' : getVal (Hmm (0:[])) = 
'8':'5':'.':'2':'.':'2':'.':'.': getVal (Hmm []) = -- base case! 
'8':'5':'.':'2':'.':'2':'.':'.':[] =  -- re-write as list 
['8', '5', '.', '2', '.', '2', '.', '.'] -- re-write as String 
"85.2.2.." 

Sie zu beachten, dass dies nur ist:

toString :: Hmm -> String 
toString (Hmm xs) = map f xs where 
    f 0 = '.' 
    f x = intToDigit x 

Um einen Maybe Int hier zu verwenden und gibt diese in die Welt der Monaden, gelten nur die gleichen Änderungen an Ihrem Code

import Data.Char (intToDigit) 

data Hmm = Hmm [Maybe Int] 
    deriving (Show, Eq) 

yd = Hmm [Just 8, Just 5, Nothing, Just 2, Nothing, Just 2, Nothing, Nothing] 

getVal :: Hmm -> String 
getVal (Hmm []) = [] 
getVal (Hmm (Nothing:xs)) = '.'   : getVal (Hmm xs) 
getVal (Hmm (Just x :xs)) = intToDigit x : getVal (Hmm xs) 

-- or equivalently 

getVal' :: Hmm -> String 
getVal' (Hmm xs) = map f xs where 
    f Nothing = '.' 
    f (Just x) = intToDigit x 
+1

vielen dank für ihre erklärung + zeit.Könntest du bitte das letzte Bit erklären (Karte f), wie es scheint, eine schöne elegante Annäherung zu sein –

+0

was ist nur 'Just 17'? auch, vgl. [Data.Maybe.maybe] (https://hackage.haskell.org/package/base-4.10.1.0/docs/Data-Maybe.html#v:maybe) –

+0

@WillNess können Sie als '[String] sammeln 'und verlasse die Funktion mit' intercalate "", aber das ist letztendlich eine andere Frage, nicht wahr? –

Verwandte Themen