我试图在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")
时工作正常,但需要稍后在
有些人可以解释为什么这不起作用以及如何解决它?
谢谢:)
答案 0 :(得分:4)
所以让我们明白这一点(请总是添加你所谈论的所有功能的类型签名!)
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
。这实际上是正确的签名,可能正是你想要的。