在 F# 中通过条件公式创建循环序列

Creating recurrent sequence by conditional formula in F#

美好的一天。 通过以下公式创建序列(可能是有限的)或列表的最佳方法是什么?

例如,从 1 到 9 将是

1, 2, 4, 5, 10, 11, 22, 23, 46

我觉得那里可以用List.fold或者List.scan,但是不知道在哪里写 yield.

您可以使用可变值和 for 循环来完成。或者,可以使用 unfold:

Seq.unfold (fun (a,i) -> 
    let a' = 
        if i % 2 = 0
        then a*2
        else a+1
    Some (a', (a',i+1)))
    (1,1)
|> Seq.append [1]

我要添加到 Torbonde 的答案中的一件事是值得使用 F# big integer literal

例如,比较以下两个答案:

//The integers rapidly become too large hence do not display correctly
let infseq = 
    (1,1)|>Seq.unfold(fun (x,i) ->
        if (i%2 = 0) 
        then Some(x,(x*2,i+1)) 
        else Some(x,(x+1,i+1)))
let first100 = infseq |>Seq.take(100)|>Array.ofSeq

let infseqBI =
    (1I,1I)|>Seq.unfold(fun (x,i)->
       if (i%2I = 0I) 
       then Some(x,(x*2I,i+1I)) 
       else Some(x,(x+1I,i+1I)))
let first100BI = infseqBI |>Seq.take(100)|>Array.ofSeq


val first100 : int [] =
  [|1; 2; 4; 5; 10; 11; 22; 23; 46; 47; 94; 95; 190; 191; 382; 383; 766; 767;
    1534; 1535; 3070; 3071; 6142; 6143; 12286; 12287; 24574; 24575; 49150;
    49151; 98302; 98303; 196606; 196607; 393214; 393215; 786430; 786431;
    1572862; 1572863; 3145726; 3145727; 6291454; 6291455; 12582910; 12582911;
    25165822; 25165823; 50331646; 50331647; 100663294; 100663295; 201326590;
    201326591; 402653182; 402653183; 805306366; 805306367; 1610612734;
    1610612735; -1073741826; -1073741825; 2147483646; 2147483647; -2; -1; -2;
    -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1;
    -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1; -2; -1|]


val first100BI : System.Numerics.BigInteger [] =
  [|1; 2; 4; 5; 10; 11; 22; 23; 46; 47; 94; 95; 190; 191; 382; 383; 766; 767;
    1534; 1535; 3070; 3071; 6142; 6143; 12286; 12287; 24574; 24575; 49150;
    49151; 98302; 98303; 196606; 196607; 393214; 393215; 786430; 786431;
    1572862; 1572863; 3145726; 3145727; 6291454; 6291455; 12582910; 12582911;
    25165822; 25165823; 50331646; 50331647; 100663294; 100663295; 201326590;
    201326591; 402653182; 402653183; 805306366; 805306367; 1610612734;
    1610612735; 3221225470; 3221225471; 6442450942; 6442450943; 12884901886;
    12884901887; 25769803774; 25769803775; 51539607550; 51539607551;
    103079215102; 103079215103; 206158430206; 206158430207; 412316860414;
    412316860415; 824633720830; 824633720831; 1649267441662; 1649267441663;
    3298534883326; 3298534883327; 6597069766654; 6597069766655; 13194139533310;
    13194139533311; 26388279066622; 26388279066623; 52776558133246;
    52776558133247; 105553116266494; 105553116266495; 211106232532990;
    211106232532991; 422212465065982; 422212465065983; 844424930131966;
    844424930131967; 1688849860263934; 1688849860263935|]

您可以递归地使用 sequence expression

let rec aSeq a =
    seq { yield! [a; a + 1]
          yield! aSeq (2 * (a + 1)) }

在序列表达式中,yield! 嵌入了另一个序列。上面的代码创建了从奇数 i 和任何 a 开始的序列。要得到完整的序列,初始化为 1:

let mySeq = aSeq 1

对于有限序列,可以使用Seq.take:

mySeq |> Seq.take 9

这导致序列 1; 2; 4; 5; 10; 11; 22; 23; 46