【问题标题】:Pass output from a function as input in another function in Haskell将函数的输出作为 Haskell 中另一个函数的输入传递
【发布时间】:2019-05-20 07:10:50
【问题描述】:

如何将一个函数的输出作为另一个函数的输入传递。

例如我有这两个功能

collatz :: (Integral a) => a -> [a]
collatz 1 = [1]  
collatz n  
    |even n = n:collatz (n `div` 2)  
    |odd n = n:collatz (n*3 + 1) 

还有我的另一个功能

length' [] = 0
length' (x:xs) = 1 + length' xs

我想计算一个列表的长度,它是我的 collat​​z 函数的输出。

最后我想完全计算这个

numLongChains :: Int  
numLongChains = length (filter isLong (map collatz [1..100]))  
    where isLong xs = length xs > 15  

但是一步一步来。

【问题讨论】:

  • 什么是chainnumLongChains 与计算 collat​​z 函数输出的列表的长度有什么关系?您似乎在描述两个不同的问题。你想回答哪一个?
  • 对不起,这是一个错误,我的链是我的 collat​​z 函数。我准备好了。首先我想计算一个 collanz 函数的输出长度。
  • 我不明白。你不喜欢你已有的代码吗?

标签: haskell input output


【解决方案1】:

你说的是function composition

-- assuming signature length' :: [a] -> Int   
composed :: (Integral a) => a -> Int
composed = length' . collatz

我不确定您所说的“逐步”是什么意思,但对于您的第二个问题,应该是:

numLongChains :: (Integral a) => [a] -> Int
numLongChains = length' . (filter isLong) . (map collatz)
    where isLong xs = length' xs > 15 

我将它设为一元函数,因此它可以与任何列表一起使用,而不仅仅是[1..100]

【讨论】:

  • 组合和组合是一样的吗?我是一步一步写的,因为我也想写自己的过滤函数。而不是用前奏函数来理解它。
  • 如何在winGHCi中调用这个?组合 = 长度'。校对
  • 是的,它们是一样的,我修正了这个错字。在 GHCi 中,你可以先定义上面写的函数,然后应用它,例如composed 5.
  • 仅供参考,这里的括号是可选的,删除它们会使该行更容易阅读 imo。
  • @Memo,起初我在回答中省略了类型签名上下文,但如果您在collatz 中有(Integral a),那么即使在composed 中也需要它。我现在已经在我的答案中添加了上下文。
【解决方案2】:

collatz 序列中的length'n\n -> length' (collatz n)。这种模式非常常见,我们给它起了一个名字:f . g = \x -> f (g x)。我们称之为“功能组合”。将上面的fgx 替换为length'collatzn,我们得到length' . collatz = \n -> length' (collatz n)。所以:

collatzLength = length' . collatz

顺便说一句,我们也可以在这里使用函数组合,而不是像你那样写isLong,尽管方式不太明显:

isLong xs = length' xs > 15
isLong = \xs -> length' xs > 15
isLong = \xs -> (>) (length' xs) 15
isLong = \xs -> (> 15) (length' xs) -- this is the less obvious bit
isLong = (> 15) . length'

所以问题是“n 的 collat​​z 序列是否长于 15?”现在可以写成:

isLongSequence = isLong . collatz

所以数字[1..100]的长序列是

filter isLongSequence [1..100]

或与

longSequences = filter isLongSequence

这是

longSequences [1..100]

现在,我们可以把numLongChains写成

numLongChains = length' . longSequences

长链的数量是长序列(列表)的数量(长度)。

现在,为了证明这与你的定义等价,你需要知道一个关于 map 和 filter 的规则(定理):

filter p . map f = filter (p . f)

所以

\xs -> filter isLong (map collatz xs)

相同
filter isLong . map collatz

相同
filter (isLong . collatz)

相同
filter isLongSequence

相同
longSequences

【讨论】:

    猜你喜欢
    • 2016-02-07
    • 2022-12-09
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2021-12-26
    • 2022-01-04
    相关资源
    最近更新 更多