我有这个:
get3th (_,_,a,_,_,_) = a
在GHCI中工作正常,但我想用GHC编译它,它给出了错误。如果我想编写一个函数来获取元组的第n个元素并且能够在GHC中运行我该怎么办? 我的所有程序如下所示,我应该怎么做?
get3th (_,_,a,_,_,_) = a
main = do
mytuple <- getLine
print $ get3th mytuple
答案 0 :(得分:0)
getLine的类型为IO String
,因此您的程序不会键入check,因为您提供的是String
而不是元组。
如果提供了适当的参数,您的程序将起作用,即:
main = do
print $ get3th (1, 2, 3, 4, 5, 6)
答案 1 :(得分:0)
您的问题是getLine
为您提供String
,但您需要某种元组。您可以通过将String
转换为元组来解决问题,例如使用内置的read
函数。这里的第三行尝试将String
解析为Int
的六元组。
main = do
mystring <- getLine
let mytuple = read mystring :: (Int, Int, Int, Int, Int, Int)
print $ get3th mytuple
但是请注意,虽然这对于学习类型等很有用,但是在实践中不应该编写这种代码。至少有两个警示标志:
你有一个元组超过三个的元组。很少需要这样的元组,并且通常可以用列表,向量或自定义数据类型替换。元组很少被临时用于将两种数据合并为一个值。如果您经常开始使用元组,请考虑是否可以创建自己的数据类型。
使用read
读取结构并不是一个好主意。 read
会在任何微小的错误中以可怕的错误消息爆炸您的程序,这通常不是您想要的。如果需要解析结构,最好使用真正的解析器。 read
对于简单的整数就足够了,但仅限于此。
答案 2 :(得分:0)
在我看来,你的混淆是在元组和列表之间。当你第一次见到Haskell时,这是一个可以理解的混乱,因为许多其他语言只有一个类似的结构。元组使用圆形的parens:(1,2)
。其中包含n个值的元组是一个类型,每个值可以是不同的类型,从而产生不同的元组类型。所以(Int, Int)
是与(Int, Float)
不同的类型,两者都是两个元组。前奏中有一些函数是两个元组的多态,即fst :: (a,b) -> a
取第一个元素。 fst
很容易使用模式匹配来定义,就像您自己的函数一样:
fst (a,b) = a
请注意,fst (1,2)
的评估结果为1
,但fst (1,2,3)
版的类型错误,无法编译。
现在,另一方面,列表可以是任何长度,包括零,并且仍然是相同的类型;但每个元素必须是相同的类型。列表使用方括号:[1,2,3]
。类型为a
的列表的类型写为[a]
。列表是通过将值附加到空列表[]
来构建的,因此包含一个元素的列表可以键入[a]
,但这是a:[]
的语法糖,其中:
是 cons 运算符,它将值附加到列表的头部。像元组可以模式匹配,你可以使用空列表和cons运算符来模式匹配:
head :: [a] -> a
head (x:xs) = x
模式匹配意味着x
的类型为a
,而xs
的类型为[a]
,它是我们想要head
的前者。 (这是一个前奏函数,有一个类似的函数tail
。)
请注意head
是一个部分函数,因为我们无法定义它在空列表中的作用。在空列表中调用它将导致运行时错误,因为您可以在GHCi中自行检查。更安全的选择是使用Maybe类型。
safeHead :: [a] -> Maybe a
safeHead (x:xs) = Just x
safeHead [] = Nothing
Haskell中的 String
只是[Char]
的同义词。因此,所有这些列表函数都可用于字符串,getLine
返回String
。
现在,在您的情况下,您需要第3个元素。您可以通过以下两种方式执行此操作:您可以拨打tail
几次,然后拨打head
,或者您可以将模式匹配为(a:b:c:xs)
。但是前奏中有另一个效用函数,(!!)
得到第n个元素。 (写这个功能是一个非常好的初学者练习)。所以你的程序可以编写
main = do
myString <- getLine
print $ myString !! 2 --zero indexed
测试给出
Prelude> main
test
's'
所以请记住,我们()
元组并且严格按照给定的长度,但可以有不同类型的成员;列表使用'[]',可以是任意长度,但每个元素必须是相同的类型。并且String
是真正的字符列表。
修改
顺便说一句,我想如果你有兴趣,我会提到有一种更简洁的方式来编写这个主要功能。
main = getLine >>= print . (!!3)