在 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
。
美好的一天。 通过以下公式创建序列(可能是有限的)或列表的最佳方法是什么?
例如,从 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
。