我想知道,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
的原因,以便调用者可以选择将f
和g
应用于哪种类型。这是从
Maybe
到List
的自然转换的示例,该转换将任何类型Maybe a
的a
接受,并生成等效列表(通过返回空列表或包装后的值作为单例列表)。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 [] = Nothing
和l2m (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/