3

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

例如:

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
[]
4

3 回答 3

4
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
于 2009-12-17T17:47:02.210 回答
4

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

let posInt n = [if n > 0 then yield n]
于 2009-12-17T18:06:40.940 回答
4

看答案

我如何将这个 Haskell 翻译成 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)]

)

于 2009-12-17T19:17:48.563 回答