Haskell 什么';s与=<;一起使用的单子&书信电报;在这个函数中?
一天一次的哈斯克尔运动把我弄糊涂了,弄得一点也回不来了。 目标是过滤掉列表中的元素,除非它与下面的元素相等。例如Haskell 什么';s与=<;一起使用的单子&书信电报;在这个函数中?,haskell,monads,Haskell,Monads,一天一次的哈斯克尔运动把我弄糊涂了,弄得一点也回不来了。 目标是过滤掉列表中的元素,除非它与下面的元素相等。例如 > filterByPair [1, 2, 2, 2, 3, 3, 4] [2,2,3] (我试图制作两个偏移量列表,将它们压缩成元组,并删除两次编号不相同的元组,例如[(2,2),(2,2),(3,3)],等等。) 但令人惊叹的简单解决方案首先使用了=,filterPairs重写为有意义的形式,以清晰明了: filterPairs xs = group xs >>
> filterByPair [1, 2, 2, 2, 3, 3, 4]
[2,2,3]
(我试图制作两个偏移量列表,将它们压缩成元组,并删除两次编号不相同的元组,例如[(2,2),(2,2),(3,3)],等等。)
但令人惊叹的简单解决方案首先使用了
=,filterPairs
重写为有意义的形式,以清晰明了:
filterPairs xs = group xs >>= init
我们将能够从这些类型中很好地了解发生了什么
xs :: Eq a => [a]
group :: Eq a => [a] -> [[a]]
init :: [a] -> [a]
(>>=) :: Monad m => m a -> (a -> m b) -> m b
(>>=)
的第一个参数是组xs::[[s]]
,因此如果我们在(>>=)
中替换m~[]
和a~[s]
,我们将得到
(>>=) :: [[a]] -> ([a] -> [s]) -> [s]
因此,我们在这里使用Monad
实例[]
,它相当于concatMap
(检查类型!)。现在我们可以再次重写filterPairs
filterPairs xs = concatMap init (group xs)
现在,如果您了解了concatMap
、init
和group
的工作原理,您应该能够了解原始filterPairs
的工作原理。group
具有类型Eq a=>[a]>[a]
。也许[2,3,4]
与您遇到的类型错误不太相关。如果你尝试的东西实际上是一个列表,那会怎么样?维基上解释了这一点:谢谢。问:你们说在列表monad中,bind相当于concatMap。你怎么知道的?它在Hackage中的任何地方都有记录吗?请注意,concatMap
仅等同于(=
> fmap (replicate 2) [2,3,4]
[[2,2],[3,3],[4,4]]
filterPairs xs = group xs >>= init
xs :: Eq a => [a]
group :: Eq a => [a] -> [[a]]
init :: [a] -> [a]
(>>=) :: Monad m => m a -> (a -> m b) -> m b
(>>=) :: [[a]] -> ([a] -> [s]) -> [s]
filterPairs xs = concatMap init (group xs)