如何让 Haskell 将函数识别为应用函子
How to get Haskell to recognize functions as applicative functors
我是 Haskell 的新手,仍然不明白如何处理他们的类型系统。我的问题是我正在使用 sequenceA 一书中的函数 Learn You a Haskell For Great Good。这是函数:
sequenceA :: (Applicative f) => [f a] -> f [a]
sequenceA = foldr (liftA2 (:)) (pure [])
我试图让它适应特定的用途,所以我写了以下函数:
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))
但这会引发编译错误:
Couldn't match type ‘[a0]’ with ‘Int’
Expected type: [Int]
Actual type: [[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))
我是 Haskell 的新手,仍然不明白如何处理他们的类型系统。我的问题是我正在使用 sequenceA 一书中的函数 Learn You a Haskell For Great Good。这是函数:
sequenceA :: (Applicative f) => [f a] -> f [a]
sequenceA = foldr (liftA2 (:)) (pure [])
我试图让它适应特定的用途,所以我写了以下函数:
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))
但这会引发编译错误:
Couldn't match type ‘[a0]’ with ‘Int’ Expected type: [Int] Actual type: [[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))