使用haskell map函数和字符串

时间:2014-11-17 11:33:49

标签: haskell map

我试图在haskell中使用map函数

我有这个:

lexi :: String -> [[String]]
lexi x = map (words.lines) x

我希望能够将字符串放入x,因此可以像这样运行

lexi ("string here")

但是得到错误

Couldn't match type ‘[Char]’ with ‘Char’
Expected type: String -> String
  Actual type: String -> [String]
In the second argument of ‘(.)’, namely ‘lines’
In the first argument of ‘map’, namely ‘(words . lines)’

Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [String]
  Actual type: String
In the second argument of ‘map’, namely ‘x’
In the expression: map (words . lines) x

我知道如果我使用

lexi = map (words.lines) 

我运行lexi ("string here")时工作正常,但需要稍后在

上使用该变量

有些人可以解释为什么这不起作用以及如何解决它?

谢谢:)

1 个答案:

答案 0 :(得分:4)

此答案涉及an old version of the question

所以让我们明白这一点(请总是添加你所谈论的所有功能的类型签名!)

function :: Char -> [String]

那么,map function的类型是[Char] -> [[String]],即String -> [[String]]。但是您希望结果只是[String],而不是三重嵌套列表。你可能想要加入两个级别的列表;通常,用于列表连接目的的函数是concat(或更一般地,来自join模块的Control.Monad。在这种情况下,您有两种不同的选择:

  • 将每次通话的结果加入function。即,不是单独映射function,而是映射join . function,其类型为Char -> String。具有所需类型String -> [String]的映射。

    lexi = map $ join . function
    
  • 加入映射的最终结果,即lexi = join . map function。这种映射和连接结果的组合实际上是一个非常常见的任务,它有一个特殊的运算符:monadic bind!

    lexi x = x >>= function
    

新版本

所以我们知道

words, lines :: String -> [String]

因此words . lines无效,因为您尝试将字符串列表提供给只接受单个字符串的函数。你当然可以做的是 map words对结果的影响,即map words . lines。这实际上是正确的签名,可能正是你想要的。