首页 > 解决方案 > Haskell - 无法匹配预期类型

问题描述

所以我试图在 Haskell 中创建一个简单的文本编辑器。我已经定义了一个自定义数据类型“TextEditor”,它由两个字符集组成,一个充当光标之前的所有字符,然后下一个是光标之后的所有字符。我已经用一些文本初始化了它。

import Data.List
import System.IO

data TextEditor = TextEditor([Char],[Char]) deriving (Show)

inputLine :: TextEditor
inputLine = TextEditor("The quick br", "own fox")

moveCursorLeft :: TextEditor -> TextEditor
moveCursorLeft (TextEditor (b, a)) = (TextEditor (b++ [head (a)]) , tail(a))

尝试加载时出现此错误。

Test.hs:10:38: error:
Couldn't match expected type `TextEditor' with actual type `(TextEditor, [Char])'
    * In the expression: (TextEditor (b ++ [head (a)]), tail (a))
      In an equation for `moveCursorLeft':
          moveCursorLeft (TextEditor (b, a))
            = (TextEditor (b ++ [head (a)]), tail (a))

Test.hs:10:51: error:
    * Couldn't match expected type `([Char], [Char])' with actual type `[Char]'
    * In the first argument of `TextEditor', namely `(b ++ [head (a)])'
      In the expression: TextEditor (b ++ [head (a)])
      In the expression: (TextEditor (b ++ [head (a)]), tail (a))

我对 Haskell 非常陌生,因此将不胜感激任何帮助。

标签: haskellcustom-data-type

解决方案


您在第二个子句中写道:

(TextEditor (b++ [head (a)]) , tail(a))

但这意味着您不构造TextEditor对象,而是构造(TextEditor, String)2 元组(尽管第一个元素仍然格式错误)。确实:

(TextEditor (b++ [head (a)]) , tail(a))

您可能正在寻找:

TextEditor (b++ [head (a)] , tail(a))

尽管如此,这仍然不是一个好主意:可能a是一个空列表,因此没有heador tail

通常最好在这里执行模式匹配:

moveCursorRight :: TextEditor -> TextEditor
moveCursorRight (t@TextEditor ([], b)) = t  -- I think?
moveCursorRight (TextEditor ((a:as), b)) = TextEditor (b ++ [a] , as)

但是现在它仍然非常低效,因为追加需要O(n)时间。一种常见的技术是使用两个列表,其中第一个是颠倒的,因此TextEditor ([1, 4, 2], [5, 1, 3, 0, 2])意味着241|51302(使用|光标)。

然后我们可以这样写:

-- In case we reverse the first item of the 2-tuple
moveCursorRight :: TextEditor -> TextEditor
moveCursorRight (t@TextEditor (b, [])) = t
moveCursorRight (TextEditor (b, (a:as))) = TextEditor ((a:b) , as)

请注意,这实际上是在所有功能中将光标向右移动,因为我们从元组的右侧元素弹出,然后向左推。


推荐阅读