Haskell将[Char]转换为Char

时间:2015-05-29 18:13:54

标签: haskell type-systems

我正在使用一个使用whte Network.WaiNetwork.Socket.Internal模块的Haskell程序。在这个程序中,我有一个函数,定义如下:

prepareIp :: Request -> [([Char], [Char])]
prepareIp req = [("Remote", head $ splitOn ":" $ show $ remoteHost req)]

最初,我把它作为monadic表达式(主要是为了可读性和清晰度),写成:

prepareIp :: Request -> [([Char], [Char])]
prepareIp req = do
     ip <- head $ splitOn ":" $ show $ remoteHost req
     [("Remote", ip)]

虽然前一个实现确实可以正常工作,但是monadic会抛出一个我无法解决的错误:它的输出类型不是[([Char], [Char])],而是[([Char], Char)] - 值{ {1}}由于某种原因被转换为单个字符而不是字符串!

我还尝试使用GHCi中的模块引用以及ip进行GHCi中的原型设计和类型检查,但无济于事,我仍然不知道导致此错误的原因。

任何人都可以告诉我为什么会发生这种类型的冲突?

1 个答案:

答案 0 :(得分:1)

你看到这个错误的原因是因为当你不需要的时候,你试图将所有东西都推到monad中。为了说明这一点,在任何地方添加显式类型签名并为[]交换m

getHostIp :: Request -> m []
getHostIp req = head $ splitOn ":" $ remoteHost req

prepareIp :: Request -> m ([Char], [Char])
prepareIp req = do
    ip <- (getHostIp req :: m Char)
    [("Remote" :: [Char], ip :: [Char])]

每当您看到<-时,右侧必须有类似m a的类型,其中m是某种monadic类型,a是该monadic动作的结果是。然后,<-的左侧有a类型。在您完全想要<-的值时,您已使用[Char]尝试从[Char]中获取值。此处let是合适的,do表示法是多余的。由于您只返回一个值,我建议您只返回(String, String)而不是[(String, String)]

prepareIp :: Request -> (String, String)
prepareIp req =
    let ip = getHostIp req
    in ("Remote", ip)