【问题标题】:Haskell List Comprehensions guards in F#F# 中的 Haskell List Comprehensions 守卫
【发布时间】:2009-12-17 17:35:03
【问题描述】:

在 Haskell 的列表推导中使用 F# 中的守卫实现类似功能的方法是什么

例如:

factors    ::  Int -> [Int]
factors    =   [x | x <-[1 .. n], n 'mod' x == 0]

factors 15
[1,3,5,15]

posInt     ::   Int -> [Int]
posInt     =    [n | n > 0]

posInt 5
[5]

posInt 0
[]

【问题讨论】:

标签: haskell f# list-comprehension


【解决方案1】:

gradbot 是对的。忠实地转换 posInt 看起来像:

let posInt n = [if n > 0 then yield n]

【讨论】:

  • 如果它大于零,则返回单个元素 n 的列表。
【解决方案2】:
let factors n = [for x in 1 .. n do if n % x = 0 then yield x]

正如 Kvb 所示,您可以使用没有序列的守卫。

let posInt n = [if n > 0 then yield n]

附注:
由于列表在 F# 中不是惰性的,因此您必须对无限系列使用序列。

let posInfinite = seq {1 .. Int32.MaxValue}

仅使用列表推导,您无法创建无限的递增整数序列。您必须使用递归或其他内置函数,如展开。 .Net 确实有一个任意长度的整数类型,称为 BigInteger。您可以通过在整数上添加“I”作为类型来使用它。此示例将返回一个真正的无限整数序列。

let posInfinite = Seq.unfold (fun i -> Some(i, i + 1I)) 1I

【讨论】:

  • 好吧,Seq.initInfinite 返回 int32 作为构造函数的类型。
  • int32 是有界的这一事实并不意味着您不能创建一个无限列表:seq { while true do yield 0 } 是一个无限的 0 列表。
  • 在 F# 和 Haskell 中,默认的 int 类型是 int32。我只是做了一个有界版本。
  • 对于 posInt 示例,我不希望创建无限列表。只是一个单例列表,如果给定数字
【解决方案3】:

查看答案

how do i translate this Haskell to F#?

概述了将 Haskell 列表理解转换为 F# 代码的一般方法。

(复制到这里方便参考:

更一般地说,我认为 Haskell 列表推导具有以下示例建议的形式,并显示了相应的 F#。

// Haskell
// [e(x,y) | x <- l1, y <- l2, pred(x,y)]
// F#
[for x in l1 do
    for y in l2 do
        if pred(x,y) then
            yield e(x,y)]

)

【讨论】:

    猜你喜欢
    • 2016-07-08
    • 1970-01-01
    • 2013-02-25
    • 2020-05-03
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    相关资源
    最近更新 更多