我想知道,Haskell中的自然转变是什么。
自然转换用以下签名描述:

F[a] ~> G[a]

例如,我可以转换:
Maybe a ~> List a

正确的?
IO怎么办,不可能自然转换对吗?
自然转型的目的是什么?

最佳答案

自然变换,而无需深入了解其背后的范畴理论,实际上只是一个多态函数。

Prelude> :set -XRankNTypes
Prelude> :set -XTypeOperators
Prelude> type (~>) f g = forall x. f x -> g x
~>运算符将类型构造函数映射到另一个类型构造函数,以这种方式对第一个类型构造函数的任何给定参数都有效。 TypeOperator扩展名是使我们可以使用~>而不是NatTrans之类的名称的原因; RankNTypes是让我们在定义中使用forall的原因,以便调用者可以选择将fg应用于哪种类型。
这是从MaybeList的自然转换的示例,该转换将任何类型Maybe aa接受,并生成等效列表(通过返回空列表或包装后的值作为单例列表)。
Prelude> :{
Prelude| m2l :: Maybe ~> [] -- Maybe a -> [a]
Prelude| m2l Nothing = []
Prelude| m2l (Just x) = [x]
Prelude| :}
Prelude> m2l Nothing
[]
Prelude> m2l (Just 3)
[3]
Prelude> m2l (Just 'c')
"c"
“inverse”将是l2m :: [] ~> Maybe,以及l2m [] = Nothingl2m (x:_) = Just x。 (我把引号取反,因为是m2l (l2m [1,2,3]) /= [1,2,3])
没有什么可以阻止您将IO用作任何一种类型构造函数(尽管IO在左侧,但也必须在右侧)。
foo :: IO ~> IO
foo a = putStrLn "hi" >> a
然后
> foo (putStrLn "foo")
hi
foo
> foo (return 3)
hi
3
另一个示例是将length视为从[]Const Int的自然转换(改编自https://bartoszmilewski.com/2015/04/07/natural-transformations/,我强烈建议阅读):
-- Isomorphic to builtin length, as Const Int is isomorphic to Int
-- Requires importing Data.Functor.Const
length' :: [] ~> Const Int
length' [] = Const 0
length' (x:xs) = Const (1 + getConst (length' xs))

关于haskell - 什么是Haskell的自然转变?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58363868/

10-12 17:38