【问题标题】:Haskell Filter Multiples of 3 from a List to a SublistHaskell 将 3 的倍数从列表过滤到子列表
【发布时间】:2023-04-08 21:58:01
【问题描述】:

我仍在尝试掌握 Haskell 和函数式编程的工作方式,我需要帮助来理解为什么我的函数不工作。我正在尝试创建一个函数,该函数将整数列表作为参数并过滤掉/返回一个子列表,该子列表包含第一个列表中 3 的任何倍数。这是我的代码:

module Main where

sublist = []

myFunc :: [Int] -> [Int]

myFunc [] = []

myFunc [t] = do
    if t `mod` 3 == 0
        then t : sublist
    else myFunc []

myFunc (h:t) = do
    if h `mod` 3 /= 0
        then myFunc t
        else do
            h : sublist
            myFunc t

这仅返回一个包含传递给函数的最后一个值的列表,并且仍然是 sublist = []。感谢您提前给我的任何建议。

【问题讨论】:

  • 您的代码看起来好像您不了解不变性的原则。声明 t : sublist 根本不会更改子列表,它只是生成一个仅包含 t 的列表(sublist 将始终为空,因为这就是不变性的工作原理 - 绑定不会改变)。
  • 这里不需要dos。在了解 monad 之前不要使用 do。 (好吧,在使用 monad 之前,您可能可以使用 do 符号和 IO 来逃避,但仅此而已。)
  • 弄清楚这段代码为什么会编译,以及编译后为什么会这样,对于中级 Haskell 程序员来说是一个很好的练习。 =D

标签: list haskell filter sublist


【解决方案1】:

我认为你需要先从精神上转换为实用风格。

例如,这是从列表中获取偶数

> filter even [1..10]
[2,4,6,8,10]

在不使用现有函数的情况下,您可以实现相同的功能

filter' :: (a -> Bool) -> [a] -> [a]
filter' _ [] = []
filter' condition (x:xs) = if condition x
                              then x : filter' condition xs
                              else     filter' condition xs

divisibleBy3 n = mod n 3 == 0

现在,你的程序可以写成

filter' divisibleBy3 inputList   

【讨论】:

  • 谢谢,这段代码很有帮助。是否有您或其他人可以推荐的资源来帮助我将精神转变为实用风格?我也尝试在 Prolog 中掌握递归函数,但我无法很好地理解它,无法有效地解决像 C++ 这样的语言对我来说很容易的问题。
  • 如果你刚开始,也许一本书更有用。我可以在 Haskell 中推荐 Bird's Thinking Functionally,但还有很多其他的,也许是免费的选项 LYAH 但我没有读过。
猜你喜欢
  • 1970-01-01
  • 2014-11-27
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多