我对Haskell真的很陌生。我有两个元组数组函数。第一拳将布尔值替换为0或1。
boolToInt :: [([Char], Bool)] -> [([Char], Int)]
boolToInt ((x, True):xs) = (x, 1): boolToInt xs
boolToInt ((x, False):xs) = (x, 0): boolToInt xs
boolToInt [] = []
第二个求和列表中的第二个值
teamNumberOfWins :: [([Char], Int)] -> Int
teamNumberOfWins [] = 0
teamNumberOfWins ((x, y):xs) = sum + y
where sum = teamNumberOfWins xs
对于第二个功能列表,必须已经具有Int值。有没有办法在第二个函数中第一个调用?我尝试过这样的事情:
teamNumberOfWins :: [([Char], Int)] -> Int
teamNumberOfWins [] = 0
teamNumberOfWins ((x, y):xs) = sum + y
where sum = teamNumberOfWins (boolToInt xs)
但是它不起作用。有人可以帮我吗?
答案 0 :(得分:4)
在你的防御中:
teamNumberOfWins :: [([Char], Int)] -> Int
teamNumberOfWins [] = 0
teamNumberOfWins ((x, y):xs) = sum + y
where sum = teamNumberOfWins (boolToInt xs)
最后一行有问题。 xs
是类型[([Char], Int)]
的值,但是boolToInt
仅被定义为对类型[([Char], Bool)]
的值起作用。 Haskell具有非常严格的类型系统(这实际上是该语言的强项之一),并且根本不允许您这样做。
您显然想做的是获取类型为[([Char], Bool)]
的列表,并应用boolToInt
,然后将teamNumberOfWins
(您的原始版本)应用于结果。这称为函数组合,Haskell具有一个非常有用的内置函数/运算符来执行此操作,这就是.
因此,您所需要做的就是保持前两个功能不变,并定义一个新功能:
teamNumberOfWins' = teamNumberOfWins . boolToInt
请注意,您还可以使用boolToInt
函数来大大简化map
的定义,该函数将一个元素的功能应用于列表的每个元素。因此:
boolToInt = map singleBoolToInt
where singleBoolToInt (x, True) = (x, 1)
singleBoolToInt (x, False) = (x, 0)