首页 > 解决方案 > 什么是 haskell 中的自然转换?

问题描述

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

F[a] ~> G[a]

例如,我可以转换:

Maybe a ~> List a

正确的?

怎么样IO,不可能自然转化吧?
自然转化的目的是什么?

标签: haskell

解决方案


一个自然的变换,不用深入到它背后的范畴论,实际上只是一个多态函数。

Prelude> :set -XRankNTypes
Prelude> :set -XTypeOperators
Prelude> type (~>) f g = forall x. f x -> g x

运算符将~>一个类型构造函数映射到另一个类型构造函数,这样它就适用于第一个类型构造函数的任何给定参数。TypeOperator扩展名让我们可以使用~>而不是像NatTrans;这样的名称。RankNTypes这是让我们在定义中使用的东西forall,以便调用者可以选择哪种类型f并将g应用于。

这是一个从Maybeto的自然转换的示例,它对任何类型List都采用 a ,并生成一个等效列表(通过返回一个空列表或作为单例列表的包装值)。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"

“逆”是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

另一个例子是从tolength的自然转换(改编自https://bartoszmilewski.com/2015/04/07/natural-transformations/,我强烈推荐阅读):[]Const Int

-- 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))

推荐阅读