2016-07-23 21 views
0

Ich lerne über anwendungsbezogene Funktoren. Im source für eine applicative Maybe, sieht die pure Funktion wie folgt aus:Applikative Funktoren rein passender nicht verpackt

instance Applicative Maybe where 
    pure = Just 
    ...etc 

Mit den Argumenten erweitert, ich denke, es sieht aus wie:

pure x = Just x 

Als ich pure (Just 5) nennen, es gibt Just 5.

Sollte es nicht Just (Just 5) zurückgeben?

Auch für List:

instance Applicative [] where 
    pure x = [x] 

Als ich pure [4,5,6] nennen es gibt [4,5,6].

Aus der Signatur sieht es wie pure [4,5,6] sollte [[4,5,6]] zurückgeben.

Kann jemand in einfachen Worten erklären, was hier passiert?


Warten, ich glaube, ich habe es - da gibt es soweit keinen Zusammenhang pure [4,5,6] nicht die Applicative für List verwendet, es ist nur den allgemeinen Fall verwenden und den gleichen Wert zurück. Ist das richtig?

+1

Versuchen Sie 'pure 3' und' (rein :: Vielleicht Int -> Vielleicht (Vielleicht Int)) $ Nur 3'.Ich denke, dass es den allgemeinen Fall benutzt und wie [ghci versucht, auf IO zu setzen] (https://downloads.haskell.org/~ghc/7.10.2/docs/html/users_guide/interactive-evaluation.html), ' pure (Nur 5) wird als IO (Maybe Int) bewertet. – Yosh

+3

Der Typ des reinen ist * nicht * 'ma -> m (ma)' - also gibt es nichts zu sagen, wenn der Wert 'x' in' reinem x' bereits innerhalb eines 'm' ist, das der' m' was rein schafft, wäre das gleiche 'm'. Wie @Yosh feststellte, wird die Eingabe von 'pure ..' in die GHCi-Eingabeaufforderung den Typ von pure auf" a -> IO a "setzen. Wenn dies nicht der Fall wäre, würde dies zu einem mehrdeutigen Typfehler führen (wie zB 'pure()' hat Typ 'Applicative f => f()') – user2407038

Antwort

6

pure ist eine überladene Funktion. Es nimmt einen Wert eines beliebigen Typs a und wickelt es in einen anwendungsspezifischen Funktor f.

ghci> :t pure 
pure :: Applicative f => a -> f a 

f wird durch den Kontext bestimmt. Wenn Sie pure x in eine Funktion übergeben, die Maybe erwartet, wird der Typ-Prüfer f ~ Maybe ableiten und Maybe 's Applicativepure x wird Just x auswerten. Ebenso, wenn Sie pure x in eine Funktion von Listen übergeben, wird der Typ-Checker die [] Instanz von Applicative verwenden und pure x wird eine Singleton-Liste zurückgeben.

ghci> :t map 
map :: (a -> b) -> [a] -> [b] -- map is a list function 
ghci> map (+1) (pure 4)  -- so when we pass in (pure 4) 
[5]       -- it means a singleton list 

In Ihrem Fall, ich nehme an, dass Sie pure x an einer GHCI Prompt sind eingeben. Wenn Sie keinen Kontext angeben (z. B. das Anwenden einer Listenfunktion auf pure x), nimmt GHCI standardmäßig an, dass Sie die IO Instanz von Applicative verwenden möchten, für die pure x eine Aktion IO ist, die x zurückgibt. GHCI führt dann pflichtgemäß die Aktion IO aus.

ghci> pure 'a' 
'a' 
ghci> pure (Just 3) 
Just 3 

Wenn die Typprüfung kann nicht sehen der Kontext basierend auf Ihren Code, können Sie den Kontext manuell über eine Typanmerkung erklären.

ghci> pure "hello" :: Maybe String 
Just "hello" 
ghci> pure (Just 3) :: Maybe (Maybe Int) 
Just (Just 3) 
ghci> pure [1,2,3] :: [[Int]] 
[[1,2,3]] 
+0

Korrekte Annahme re: GHCI Prompt, ich hätte das erwähnen sollen. Interessant, dass es den IO-Kontext braucht, das war der Teil, den ich vermisste. Vielen Dank! – Ben