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

Gab*_*ega -1 haskell

我已经声明了一个类型:

type Foo = (Char, Char, Char)
Run Code Online (Sandbox Code Playgroud)

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

我目前的尝试是;

parseFoo :: String ? Maybe Foo
parseFoo str = f where
    f (a, _, _) = str[0]
    f (_, b, _) = str[1]
    f (_, _, c) = str[2]
Run Code Online (Sandbox Code Playgroud)

这是返回错误:

Illegal operator ‘?’ in type ‘String ? Maybe Foo’
Use TypeOperators to allow operators in types
Run Code Online (Sandbox Code Playgroud)

我的问题是:

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

  • 我是否在正确的轨道上?

Wil*_*sem 5

如果我以正确的方式理解它,您希望将字符串的前三个字符存储到一个类型中Foo(它是包含三个Chars的 3 元组的别名)。

签名似乎是正确的(Maybe如果出现问题,最好返回 a ,这里的字符串可能包含少于三个字符)。一个问题是你写了一个箭头字符,?而在 Haskell 中使用签名->(两个 ASCII 字符,一个破折号和一个大于号)。

所以我们可以将签名定义为:

parseFoo :: String -> Maybe Foo
Run Code Online (Sandbox Code Playgroud)

现在第二个问题是你在这里定义了一个fFoos映射到Strings的函数,反之亦然。您还使用了在 C/C++/C#/Java 编程语言家族中经常用于索引的语法,但是 Haskell 中的索引是使用(!!)运算符完成的,并且由于您反向定义函数,因此不会帮助。

字符串是一个列表CharS,所以:

type String = [Char]
Run Code Online (Sandbox Code Playgroud)

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

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

对于前者,我们返回一个包含这些字符的 3 元组(包含在 a 中Just),对于后者,我们返回Nothing

parseFoo :: String -> Maybe Foo
parseFoo (a:b:c:_) = Just (a, b, c)
parseFoo _ = Nothing
Run Code Online (Sandbox Code Playgroud)

或者如果我们不想成功解析超过三个字符的字符串:

parseFoo :: String -> Maybe Foo
parseFoo [a, b, c] = Just (a, b, c)
parseFoo _ = Nothing
Run Code Online (Sandbox Code Playgroud)