在我的小程序中解析模式中的错误


left :: [String]->[Char]->Char
left [] _ = []
left (x:xs) (head xs) = x    -- it says error at head

我使用了正确的括号,但仍然出现解析错误。顺便说一句,我正在尝试获取列表中的先前元素,例如[["A"],["B"],["C"],["D"],["E"]].也许我还有其他一些错误。请纠正我.

第二个问题是如何选择以前的元素以前的索引字符。例如给函数这个列表[["J","O","H","N"],["A","L","I","C","E"]]和"C",我想期望得到"H"。我的意思是"C"是第二个元素的第4个索引,"H"是以前的元素第三个索引。提前感谢

如果我理解你很好,你需要一个函数,它在String列表中找到一个字符,并在前面的索引处返回前面字符串的字符。

像这样:

f ["JOHN", "ALICE"] 'C' == 'H'

首先,您需要知道Char文字在Haskell('A')中用简单引号分隔,String文字用双引号("ABC")分隔。

因为在Haskell中String[Char]的别名,"ABC"等价于['A', 'B', 'C']

也就是说,在Haskell中,你不能定义这样的函数:f a a = stuff。全康会抱怨a被多次定义。 因此,要检查两个参数是否具有某些属性,您需要保护模式。

所以我会像这样写你的第一个函数:

left :: [String] -> String -> String
left [] _ = ""
left [x] _ = ""
left (x1:x2:xs) str
| x2 == str = x1
| otherwise = left (x2:xs) str

对于你的第二个问题:

import Data.List
f :: [String] -> Char -> Maybe Char
f [] _ = Nothing
f [a] _ = Nothing
f (x1:x2:xs) c
| Just i <- elemIndex c x2 = Just $ x1 !! (i-1)
| otherwise = f (x2:xs) c

笔记:

  • left还应返回Maybe String,以防找不到str或未找到或首先找到。
  • f不检查x1是否真的足够长
  • 通常在 Haskell 中,list 参数是最后一个,以允许咖喱。

编辑:

一种更聪明的zip方法(在模块Data.List中)。

f :: [String] -> Char -> Maybe Char
f [] _ = Nothing
f [_] _ = Nothing
f (x1:"":xs) c = f xs c
f (x1:x2:xs) c = f' (zip x1 (tail x2))
where f' [] = f (x2:xs) c
f' ((a,b):l) = if b == c then a else f' l

此版本不会崩溃。它将返回满足"是第 n 个字符串中的第 m 个字符,而第 (n+1)个字符串中的 (m+1)个字符"的第一个字符是c。结果将被包装在Maybe(Just 'H')。否则,它返回Nothing(Maybe大致是 Haskell 的可为空类型)。

zip是一个将两个列表合并为一个对列表的函数:

zip ['a', 'b', 'c'] [1, 2] == [('a', 1), ('b', 2)]

生成的列表的大小是最小的列表之一。所以在示例中,发生的情况是:

zip "JOHN" (tail "ALICE") == [('J','L'), ('O', 'I'), ('H', 'C'), ('N', 'E')]

然后,您只需检查第二个字符是否是搜索的字符,然后返回该对的第一个字符。

要访问"上一个"列表元素,您必须使用不同的递归。 例如

foo []  = baseCase
foo [x] = onlyOneElement x
foo (x1:x2:xs) = use x1 x2 (foo (x2:xs))

调用foo [1,2,3,4,5]时,您可以访问x1=1, x2=2。递归时,您将可以访问x1=2, x2=3,依此类推。因此,您可以将x2视为"当前"元素,x1是前一个元素。

相关内容

  • 没有找到相关文章

最新更新