Haskell List Понимания охранников в F # - PullRequest
3 голосов
/ 17 декабря 2009

Как реализовать аналогичные функциональные возможности в Хаскелле из списочных представлений со средствами защиты в 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
[]

Ответы [ 3 ]

4 голосов
/ 17 декабря 2009

Градбот прав. Правильное преобразование posInt будет выглядеть так:

let posInt n = [if n > 0 then yield n]
4 голосов
/ 17 декабря 2009

См. Ответ на

как мне перевести этот Haskell на F #?

, который описывает общий способ превратить понимание списка Хаскелла в код 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)]

)

4 голосов
/ 17 декабря 2009
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
...