我已经声明了类型:
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
我的问题是:
如何防止编译时出现此错误?
我什至在正确的轨道上吗?
答案 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]
因此,我们可以定义两种模式:
对于前者,我们返回包含这些字符的三元组(用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