哈斯克尔的传感器和单态限制 [英] Transducers in Haskell and the monomorphism restriction
本文介绍了哈斯克尔的传感器和单态限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
{ - #LANGUAGE RankNTypes# - }
导入Prelude隐藏(foldr)
导入Data.Foldable
类型Reducer ba = a - > b - > b
型传感器a b = forall t。减速器t b - > Reducer t a
class可折叠c => Collection c其中
insert :: a - > c a - > c a
empty :: c a
reduce :: Collection c =>传感器a b - > c a - > c b
reduce f = foldr(f insert)empty
mapping ::(a - > b) - >传感器ab
映射fgx = g(fx)
现在我想定义一个通用 map
函数。因此,我将上面的代码加载到GHCi中:
Prelude> :load Transducer
[1的1]编译Main(Transducer.hs,解释)
好了,加载模块:Main。
* Main>让map = reduce。映射
< interactive>:3:20:
无法匹配类型'Reducer t0 b1 - >减速机t0 a1'
与'forall t。减速器t b - > Reducer t a'
预期类型:(a1 - > b1) - >换能器a b
实际类型:(a1 - > b1) - >减速机t0 b1 - > Reducer t0 a1
相关绑定包括
map ::(a1 - > b1) - > c a - > c(绑定在< interactive>:3:5)
在'(。)'的第二个参数中,即'映射'
在表达式:reduce中。映射
* Main>让map f = reduce(映射f)
* Main> :t map
map :: Collection c => (a - > b) - > c a - > c b
所以我无法定义 map = reduce。映射
。不过,我可以定义 map f = reduce(映射f)
。我相信这个问题是由单态限制。我真的很想写 map = reduce。映射
而不是映射f = reduce(映射f)
。因此,我有两个问题:
- 是什么导致了这个问题?是否确实是单态限制?
- 如何解决这个问题?
解决如果你使
Transducer
a newtype
,那么GHC将会找出更多的类型更好。存在型变量不会转义范围—换能器将保持多态。 换句话说,用下面的定义 map = reduce。 mapping
works
{ - #LANGUAGE RankNTypes# - }
import Prelude隐藏(foldr,map,(。),id)
导入Control.Category
导入Data.Foldable
类型Reducer ba = a - > b - > b
newtype传感器a b = MkTrans {unTrans :: forall t。减速器t b - > Reducer t a}
class可折叠c => Collection c其中
insert :: a - > c a - > ca
empty :: ca
实例集合[]其中
insert =(:)
empty = []
reduce ::集合c =>传感器a b - > c a - > c b
reduce f = foldr(unTrans f insert)empty
mapping ::(a - > b) - >换能器a b
映射f = MkTrans $ \g x - > g(f x)
filtering ::(a - > Bool) - >换能器a
过滤f = MkTrans $ \g x y - >如果f x则g x y else y
map :: Collection c => (a - > b) - > c a - > c b
map = reduce。映射
filter :: Collection c => (a - > Bool) - > c a - > c a
filter = reduce。过滤
实例类别传感器其中
id = MkTrans id
MkTrans f。 MkTrans g = MkTrans $ \x - > g(f x)
dub :: Num a => a - > a
dub x = x + x
test1 :: [Int]
test1 = reduce(过滤偶数映射配音)[1..10]
- - [2,4,6,8,10,12,14,16,18,20]
test2 :: [Int]
test2 = reduce(映射配音过滤) [1..10]
- [4,8,12,16,20]
< hr>
* Main> :减少。映射
reduce。 mapping :: Collection c => (a - > b) - > c a - > cb
*Main> :t reduce . mapping
reduce . mapping :: Collection c => (a -> b) -> c a -> c b
Also you could want to check http://www.reddit.com/r/haskell/comments/2cv6l4/clojures_transducers_are_perverse_lenses/
where definition is type Transducer a b =:: (a -> Constant (Endo x) a) -> (b -> Constant (Endo x) b)
and various other. Also other interestig discussion.
这篇关于哈斯克尔的传感器和单态限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文