繁体   English   中英

如何让 Haskell 将函数识别为应用函子

[英]How to get Haskell to recognize functions as applicative functors

我是 Haskell 的新手,仍然不明白如何处理他们的类型系统。 我的问题是我正在玩《 Learn You a Haskell For Great Good 》一书中的序列A function 。 这是 function:

sequenceA :: (Applicative f) => [f a] -> f [a]
sequenceA = foldr (liftA2 (:)) (pure [])

我试图让它适应特定的用途,所以我写了以下 function:

binner :: Int -> [Int -> Int]
binner n = (map (\x -> bin x) [n, (n-1) .. 1])
  where bin n = (`mod` 2) . (`div` 2^(n-1))

单独使用这些功能没有问题。 例如,以下在 GHCi 中效果很好:

sequenceA (binner 4) 10

如果我在 GHCi 中键入以下内容,

:t (sequenceA (binner 4))

它显示类型为:

(sequenceA (binner 4)) :: Int -> [Int]

但是,我不知道如何组合这些功能。 直觉上,似乎我应该能够使用 GHCi 显示的相同类型执行以下操作:

binner :: Int -> [Int]
binner n = foldr (liftA2 (:)) (pure []) $ (map (\x -> bin x) [n, (n-1) .. 1])
  where bin n = (`mod` 2) . (`div` 2^(n-1))

但这会引发编译错误:

无法将类型“[a0]”与“Int”匹配预期类型:[Int] 实际类型:[[a0]]

我尝试弄乱类型声明,但还没有弄清楚如何解决它。

谢谢您的帮助!

您尝试将sequenceA (binner 4)的类型与基本上\n -> sequenceA (binner n)的主体一起使用。 由于您编写的内容需要一个Int而您提供给:t的内容却没有,因此您需要在类型签名的开头添加一个Int ->来表示n

binner :: Int -> Int -> [Int]
binner n = foldr (liftA2 (:)) (pure []) $ (map (\x -> bin x) [n, (n-1) .. 1])
  where bin n = (`mod` 2) . (`div` 2^(n-1))

您可以改为保留类型,但对 4 进行硬编码:

binner :: Int -> [Int]
binner = foldr (liftA2 (:)) (pure []) $ (map (\x -> bin x) [4, (4-1) .. 1])
  where bin n = (`mod` 2) . (`div` 2^(n-1))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM