Haskell中元组和列表的不同应用行为
比如说,Haskell中元组和列表的不同应用行为,haskell,applicative,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] &
-- 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]
--Num a=>([Char],a->a)([Char],a)
>(“你好”(*6))(“世界”,7)
(“你好,世界”,42)
--数值a=>[a->a][a]
> [(*7),(*6)] [6,7]
[42,49,36,42]
--数值a=>[[Char],a->a][[Char],a]
>[“你好”(*6)][“世界”,7]
:17:2:
无法匹配预期的类型“[Char]->[Char]”
实际类型为“[Char]”
在表达中:“你好”
在“()”的第一个参数中,即“[“hello”,(*6)]”
在表达式中:[“你好”(*6)][“世界”,7]
对于三个示例,
显示了不同的行为。会发生什么?为什么在第三种情况下,它需要一个[Char]->[Char]
而不是像第一种情况一样的[Char]
。更重要的是,即使元组中只有[Char]
,
也将它们组合在一起。不同之处在于列表是同质的,而元组不是:列表只包含相同类型的元素,而元组不必包含相同类型的元素
即使不看应用程序,函子也已经显示出一个主要区别:
fmap succ [1,2,3] ==> [2,3,4]
fmap succ ("a", 4) ==> ???
认为fmap
将succ
应用于“a”
是不合逻辑的。发生的情况是,只有第二个组件受到影响:
fmap succ ("a", 4) ==> ("a", 5)
事实上,看看这些例子:
instance Functor [] where ...
instance Functor ((,) a) where ...
注意a
类型。在列表实例中,[]
只接受一个类型参数,即受fmap
影响的类型。在(,)
中,我们有两个类型参数:一个是固定的(到a
),并且在应用fmap
时不会改变,只有第二个会改变
请注意,当两个类型参数都被强制为相同时,理论上可以接受函子(,)
的实例。例如:
instance Functor (\b -> (b,b)) where ...
但哈斯克尔不允许这样做。如果需要,需要一个新类型的包装器:
newtype P b = P (b,b)
instance Functor P where
fmap f (P (x,y)) = P (f x, f y)
应用程序是满足以下条件的数据类型和
pure
和
定义的任意组合:
[identity]纯id v=v
[成分]纯(.)u v w=u(v w)
[同态]纯f纯x=纯(f x)
[interchange]u pure y=pure($y)u
这些法则确保了
的行为非常类似于函数应用程序,但它发生在某种依赖于应用程序的“特殊上下文”中。对于Maybe
的情况,上下文是可能缺少值。对于元组,上下文是“伴随每个值的幺半体注释”
pure
和
可以为不同的数据类型做非常不同的事情,只要它们遵守法律
事实上,相同的数据类型可以以不同的方式应用。列表有一个应用实例,其中
“获取所有组合”,还有一个用辅助newtype实现的实例,其中
将列表拉到一起并pure
构造一个无限的列表。导致了这一点,但对于列表它是。[[Char],a->a]
,或者更一般地说[a,b]
不是haskell的列表。哦,谢谢,我的笨蛋@FrankyThanks,这就解决了问题。但有没有理由用这种方式定义列表和元组的应用程序?或者只是一个惯例@任性
[identity] pure id <*> v = v
[composition] pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
[homomorphism] pure f <*> pure x = pure (f x)
[interchange] u <*> pure y = pure ($ y) <*> u