Haskell:将字符串解析为自定义类型

时间:2018-09-04 11:48:30

标签: haskell

我已经声明了类型:

type Foo = (Char, Char, Char)

并且希望能够解析3个字母的字符串“ ABC”以产生输出Foo,其中每个ABC作为该类型的三个属性。

我目前的尝试是;

parseFoo :: String → Maybe Foo
parseFoo str = f where
    f (a, _, _) = str[0]
    f (_, b, _) = str[1]
    f (_, _, c) = str[2]

这将返回错误:

Illegal operator ‘→’ in type ‘String → Maybe Foo’
Use TypeOperators to allow operators in types

我的问题是:

  • 如何防止编译时出现此错误?

  • 我什至在正确的轨道上吗?

1 个答案:

答案 0 :(得分:4)

如果我以正确的方式理解它,则希望将字符串的前三个字符存储为类型Foo(这是包含三个Char的3元组的别名)

签名似乎是正确的(如果出现问题,最好返回Maybe,并且该字符串可能少于三个字符)。但是,问题是您写了一个箭头字符,而Haskell中的签名使用了->(两个ASCII字符,一个破折号和一个大于符号)。

因此我们可以将签名定义为:

parseFoo :: String -> Maybe Foo

现在,第二个问题是您在此处定义一个函数f,该函数将Foo映射到String,因此相反。您还使用了C / C ++ / C#/ Java编程语言家族的语言中经常用于索引的语法,但是Haskell中的索引是通过(!!)运算符完成的,并且由于您在反向,将无济于事。

字符串是Char s的列表,因此:

type String = [Char]

因此,我们可以定义两种模式:

  1. 具有三个(或更多)字符的列表;和
  2. 少于三个字符的列表。

对于前者,我们返回包含这些字符的三元组(用Just包装),对于后者,我们返回Nothing

parseFoo :: String -> Maybe Foo
parseFoo (a:b:c:_) = Just (a, b, c)
parseFoo _ = Nothing

或者如果我们不想成功地解析三个以上字符的字符串:

parseFoo :: String -> Maybe Foo
parseFoo [a, b, c] = Just (a, b, c)
parseFoo _ = Nothing