'Just'和'pure'之间的区别

时间:2016-09-13 12:21:36

标签: haskell functor applicative

Just (+) <*> Just 3 <*> Just 5
  

只是8

pure (+) <*> Just 3 <*> Just 5
  

只是8

pure (*3) <*> [0..10]
  

[0,3,6,9,12,15,18,21,24,27,30]

Just (*3) <*> [0..10]
  

无法将类型'[]'与'Maybe'匹配

     

预期类型:也许b

     

实际类型:[b]

     

在'(&lt; *&gt;)'的第二个参数中,即'[0 .. 10]'

     

在表达式中:Just(* 3)&lt; *&gt; [0 .. 10]

     

在'it'的等式中:it = Just(* 3)&lt; *&gt; [0 .. 10]

pureJust何时可以互换,何时不同?

2 个答案:

答案 0 :(得分:10)

pure是一个重载操作。它是为实现Applicative类的所有类型定义的。其中一种类型是Maybe。因此,pure在该上下文中与Just相同。但是还有其他类型也实现了Applicative,例如[](列表)。在这种情况下,pure表示单例(即获取单个值并返回包含该值的单元素列表的函数)。所以

pure (*3) <*> [0..10]

真的意味着:

[(*3)] <*> [0..10]

而不是

Just (*3) <*> [0..10]

在最后一个例子中,你试图将列表与maybes混合,这就是GHC拒绝它的原因。一般来说,haskell根据上下文确定pure的确切含义,例如如果您尝试将其与maybes一起使用,它会将其解释为Just,如果您将其用于列表,则将其解释为单身。

答案 1 :(得分:6)

pure函数返回多态值:

Prelude> :t pure "foo"
pure "foo" :: Applicative f => f [Char]

对于Maybepure刚定义为Just

instance Applicative Maybe where
    pure = Just
    -- ...

其他类型提供不同的定义;例如,它被列为

列表
instance Applicative [] where
    pure x    = [x]
    -- ...

指定返回值的类型告诉Haskell Applicative实例用于定义pure

Prelude> pure "foo" :: [[Char]]
["foo"]
Prelude> pure "foo" :: Maybe [Char]
Just "foo"

除了提供显式类型之外,Haskell还可以根据值的使用方式推断使用哪种类型。例如,(<*> [1..5]) :: (Num a, Enum a) => [a -> b] -> [b],因此在pure (+3) <*> [1..5]中,我们知道pure (+3)必须包含[a -> b]类型。同样,在pure (+3) <*> Just 5中,我们知道pure (+3)必须具有Maybe (a->b)类型。

通常,在任何表达式pure f <*> g中,g的类型将确定需要返回的值pure f的类型。