簡體   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