首页 > 解决方案 > 在 Haskell 中的另一个函数内部调用函数

问题描述

我对 Haskell 真的很陌生。我有两个用于元组数组的函数。第一个用 0 或 1 替换 Bool 值。

boolToInt :: [([Char], Bool)] -> [([Char], Int)]
boolToInt ((x, True):xs)        = (x, 1): boolToInt xs
boolToInt ((x, False):xs)       = (x, 0): boolToInt xs
boolToInt []                    = []

Second 对列表中的第二个值求和

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)

但它不起作用。有人能帮我吗?

标签: haskell

解决方案


为你辩护:

teamNumberOfWins :: [([Char], Int)] -> Int
teamNumberOfWins  []            = 0
teamNumberOfWins ((x, y):xs)    = sum + y
   where sum = teamNumberOfWins (boolToInt xs)

最后一行有问题。xs是 type 的值[([Char], Int)],但boolToInt仅被定义为对 type 的值起作用[([Char], Bool)]。Haskell 有一个非常严格的类型系统(这实际上是该语言的优势之一),根本不允许你这样做。

您显然想要做的是获取 type 列表,然后[([Char], Bool)]apply boolToInt,然后 apply teamNumberOfWins(您的原始版本)到结果。这被称为函数组合,Haskell 有一个非常有用的内置函数/运算符来执行此操作,这很简单.

因此,您需要做的就是保持前 2 个函数不变,并定义一个新函数:

teamNumberOfWins' = teamNumberOfWins . boolToInt

请注意,您还可以大大简化boolToInt使用map函数的定义,它将一个元素的函数应用于列表的每个元素。因此:

boolToInt = map singleBoolToInt
  where singleBoolToInt (x, True) = (x, 1)
        singleBoolToInt (x, False) = (x, 0)

推荐阅读