yua*_*ili 4 haskell applicative
例如,
-- Num a => ([Char], a -> a) <*> ([Char], a)
> ("hello ",(*6)) <*> ("world",7)
("hello world",42)
-- Num a => [a -> a] <*> [a]
> [(*7),(*6)] <*> [6,7]
[42,49,36,42]
-- Num a => [[Char], a -> a] <*> [[Char], a]
> ["hello ",(*6)] <*> ["world",7]
<interactive>:17:2:
Couldn't match expected type ‘[Char] -> [Char]’
with actual type ‘[Char]’
In the expression: "hello "
In the first argument of ‘(<*>)’, namely ‘["hello ", (* 6)]’
In the expression: ["hello ", (* 6)] <*> ["world", 7]
Run Code Online (Sandbox Code Playgroud)
对于三个示例,<*>显示了不同的行为。怎么了?为什么在第三种情况下,它期望一个[Char] -> [Char]而不是[Char]在第一种情况下。而且,即使只有[Char]元组,也可以<*>将它们组合在一起。
不同之处在于列表是齐次的,而元组则不是:列表仅包含相同类型的元素,而元组则不必。
即使不看任何应用,函子也已经显示出主要区别:
fmap succ [1,2,3] ==> [2,3,4]
fmap succ ("a", 4) ==> ???
Run Code Online (Sandbox Code Playgroud)
争论fmap适用succ于事实是不合逻辑的"a"。发生的是只有第二个组件受到影响:
fmap succ ("a", 4) ==> ("a", 5)
Run Code Online (Sandbox Code Playgroud)
实际上,请查看实例:
instance Functor [] where ...
instance Functor ((,) a) where ...
Run Code Online (Sandbox Code Playgroud)
注意a类型。在list实例中,[]仅接受一个type参数,而该类型是受所影响的类型fmap。在其中,(,)我们有两个类型参数:一个是固定的(to a),并且在应用时不会更改fmap-只有第二个是固定的。
注意,从理论上讲,有可能接受Functor (,)两个类型参数被强制相同的实例。例如,
instance Functor (\b -> (b,b)) where ...
Run Code Online (Sandbox Code Playgroud)
但是Haskell不允许这样做。如果需要,则需要一种新型包装器:
newtype P b = P (b,b)
instance Functor P where
fmap f (P (x,y)) = P (f x, f y)
Run Code Online (Sandbox Code Playgroud)