为什么字符串列表突然出现了一系列字符串列表?

时间:2015-11-25 13:34:18

标签: list haskell types

我有一个功能:

setDisplays :: Char -> [String] -> IO()
setDisplays mode dIds
    | mode == 'l' = chngDispl (head dIds)
    | mode == 'e' = chngDispl (tail dIds)
    where
      chngDispl on = mapM_ (\id -> callProcess "xrandr" ["--output", id, "--auto"]) on

获取带有xrandr提供的显示ID的字符串列表,该列表看起来像["eDP1", "HDMI1"]。该列表通过绑定setDisplays

传递给IO ()
getDisplays >>= setDisplays 'e'

现在,我收到以下错误消息: parser.hs:50:37:

    Couldn't match type ‘Char’ with ‘[Char]’
    Expected type: [[String]]
      Actual type: [String]
    In the first argument of ‘head’, namely ‘dIds’
    In the first argument of ‘chngDispl’, namely ‘(head dIds)’
Failed, modules loaded: none.

我没有得到。甚至ghc-mod告诉我,第一次提到的名称dIds标识[String],当我在函数调用中使用ghc-mod进行类型检查时,它标识[[[Char]]]。这里发生了什么?

2 个答案:

答案 0 :(得分:4)

您在head上使用dIds并期望成为[String]。因此,类型推断告诉我们,以这种方式使用的dIds应该是[[String]]类型。

此外,您在tail下方的一行使用dIds。那不是匹配。

答案 1 :(得分:4)

如果dIds[String],那么head的结果将是String,但chngDispl需要[String]。这就是为什么编译器认为head的参数应该是[[String]]

在列表中换行head dIds,错误应该消失。

您通常应该避免使用head并使用模式匹配。您可以像这样重写您的函数:

setDisplays :: Char -> [String] -> IO()
setDisplays mode (id:ids)
    | mode == 'l' = chngDispl [id]
    | mode == 'e' = chngDispl ids
    where
      chngDispl on = mapM_ (\id -> callProcess "xrandr" ["--output", id, "--auto"]) on

请注意,如果列表为空,这将失败(head也是如此),您也应该处理这种情况。