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

时间:2017-03-25 08:19:16

标签: haskell parse-error

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&#34 ; ,我希望得到" H"。我是说" C"是第二元素第四指数" H"是以前的元素第3个索引。 Thnx提前

2 个答案:

答案 0 :(得分:2)

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

类似的东西:

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

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

由于在Haskell中String[Char]的别名,"ABC"相当于['A', 'B', 'C']

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

所以我会写下你的第一个函数:

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参数是最后一个,允许currying

编辑:

使用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的第一个字符。结果将包含在MaybeJust 'H')中。否则,它返回NothingMaybe大致是Haskell的可空类型。)

zip是一个函数,它将两个列表合并在一对列表中:

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

结果列表的大小是最小的列表之一。所以在这个例子中,会发生什么:

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

然后你必须检查第二个字符是否是搜索过的字符,然后返回该字符串的第一个字符。

答案 1 :(得分:1)

可以访问&#34;之前的&#34; list元素,您必须使用不同的递归。 E.g。

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视为&#34;当前&#34;元素,x1是前一个元素。