调用Haskell中另一个函数的内部函数
我对哈斯克尔真的很陌生。我有两个元组数组函数。第一个将布尔值替换为0或1调用Haskell中另一个函数的内部函数,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 [] = [] Second对列表中的第二
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)
但它不起作用。有人能帮我吗?为您辩护:
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
请注意,您还可以使用map
函数大大简化boolToInt
的定义,该函数将一个元素的函数应用于列表中的每个元素。因此:
boolToInt = map singleBoolToInt
where singleBoolToInt (x, True) = (x, 1)
singleBoolToInt (x, False) = (x, 0)
如果要调用第一个函数,则输入类型应包含布尔值。另外,您不需要在每次递归调用时转换整个列表:转换一次就足够了。@chi,我应该在什么地方调用函数一次?我是这样想的,但我不知道该在哪里做。
sum[如果b那么ls中的其他0 |(|,b)]
?@seigailion-Robin下面展示了如何做:你可以定义fys=f2(boolToInt ys)其中f2[]=;f2(x:xs)=……
。关键是,您需要定义一个辅助递归函数(f2
)处理“带int的列表”,然后用修改后的列表调用它。请注意,您实际上不需要boolToInt
,因为Bool
已经有一个Enum
实例,它允许您编写teamNumberOfWins=((x,y):xs)=fromEnum y+teamNumberOfWins xs
,或使用Elmex80的列表理解,sum[fromEnum b |(|,b)在我看来,为singleBoolToInt
引入fromEnum
是值得的。如果我们想进一步简化,我们可以让teamNumberOfWins=length.filter snd
。但我喜欢Robin的答案,因为它向OP解释了错误,并提出了OP应该可以理解的修复方案。相比之下,只是给出了一个神秘的s像我这样的解决方案不会很有帮助,至少在OP学会一些中级Haskell之前是这样。谢谢@chi和@ATayler-我同意你的评论,我没有在地图
之外追求简化,部分原因是懒惰和时间限制,部分原因是我自己对Haskell的熟悉程度远不如你们(当然应该发现length.filter snd
version。)我主要想向OP展示他到底做错了什么,以及最“直接”(尽管不是“最佳”)的修复方法。