gpt4 book ai didi

haskell - Haskell monad 链接中的类型检查错误

转载 作者:行者123 更新时间:2023-12-02 21:25:32 25 4
gpt4 key购买 nike

我是 Haskell 新手,我只是按照 RWH 上的示例进行操作。我在使用第 14 章的以下程序时遇到问题:

import qualified Data.Map as M

type PersonName = String
type PhoneNumber = String
type BillingAddress = String
data MobileCarrier = Honest_Bobs_Phone_Network
| Morrisas_Marvelous_Mobiles
| Petes_Plutocratic_Phones
deriving (Eq, Ord)

findCarrierBillingAddress :: PersonName
-> M.Map PersonName PhoneNumber
-> M.Map PhoneNumber MobileCarrier
-> M.Map MobileCarrier BillingAddress
-> Maybe BillingAddress
-- This will work
findCarrierBillingAddress person phoneMap carrierMap addressMap = do
phone <- M.lookup person phoneMap
carrier <- M.lookup phone carrierMap
address <- M.lookup carrier addressMap
return address

-- This will NOT work:
findCarrierBillingAddress person phoneMap carrierMap addressMap =
return person >>=
lookup phoneMap >>=
lookup carrierMap >>=
lookup addressMap
where lookup = flip M.lookup

似乎当使用 >>= 以 monad 链接格式编写 findCarrierBillingAdres 时,它只是不进行类型检查:

/home/bruce/Programming/haskell/real/ch14/hello.hs:21:9:
Couldn't match type `[Char]' with `MobileCarrier'
Expected type: MobileCarrier -> Maybe BillingAddress
Actual type: PersonName -> Maybe BillingAddress
In the return type of a call of `lookup'
In the second argument of `(>>=)', namely `lookup addressMap'
In the expression:
return person >>= lookup phoneMap >>= lookup carrierMap
>>= lookup addressMap

/home/bruce/Programming/haskell/real/ch14/hello.hs:21:16:
Couldn't match type `MobileCarrier' with `[Char]'
Expected type: M.Map PersonName BillingAddress
Actual type: M.Map MobileCarrier BillingAddress
In the first argument of `lookup', namely `addressMap'
In the second argument of `(>>=)', namely `lookup addressMap'
In the expression:
return person >>= lookup phoneMap >>= lookup carrierMap
>>= lookup addressMap
Failed, modules loaded: none.

问题是..为什么使用 >>= 的第二种格式不会进行类型检查?

最佳答案

这只是单态限制再次发挥作用。由于您有一个没有类型签名的模式绑定(bind),因此推断的类型是单态的,因此由第一次使用决定。

直接改成

lookup m k = flip M.lookup m k

甚至

lookup m = flip M.lookup m

你只需要说服 GHC 概括该功能,而当它只是一个简单的模式绑定(bind)时它不会这样做。添加参数会将其变成函数绑定(bind),这意味着它将被完全泛化。

如果我在那里有点失去你,我已经 blogged about this

关于haskell - Haskell monad 链接中的类型检查错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17961273/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com