在Haskell的另一个函数内部调用函数

时间:2019-04-02 10:21:39

标签: haskell

我对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)

但是它不起作用。有人可以帮我吗?

1 个答案:

答案 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)