سؤال

أتساءل لماذا لا يدعم F-Sharp Infinity.

هذا من شأنه أن يعمل في روبي (ولكن ليس في F#):

let numbers n = [1 .. 1/0] |> Seq.take(n)

-> System.DivideByzeroException: حاولت الانقسام على الصفر.

يمكنني كتابة نفس الوظيفة بطريقة معقدة للغاية:

let numbers n = 1 |> Seq.unfold (fun i -> Some (i, i + 1)) |> Seq.take(n)

-> الأعمال

ومع ذلك أعتقد أن الأول سيكون أكثر وضوحًا. لا يمكنني العثور على أي طريقة سهلة لاستخدام اللانهاية المكتوبة ديناميكيًا في F#. هناك الكلمة الرئيسية اللانهائية ولكنها تعويم:

let a = Math.bigint +infinity;;

System.OverflowException: لا يمكن أن تمثل BigInteger اللانهاية. في system.numerics.biginteger..ctor (قيمة مزدوجة) على. $ fsi_0045.main@() توقف بسبب الخطأ


تحرير: يبدو أن هذا يعمل بالتكرار:

let numbers n = Seq.initInfinite (fun i -> i+1) |> Seq.take(n)
هل كانت مفيدة؟

المحلول

بادئ ذي بدء ، فإن قوائم F# ليست كسول ، (لست متأكدًا من قوائم روبي كسول) ، لذلك حتى مع وجود فكرة عامة عن اللانهاية ، لا يمكن أن يعمل مثالك الأول أبدًا.

ثانياً ، لا توجد قيمة اللانهاية في int32. فقط maxvalue. هناك اللانهاية الإيجابية والسلبية في ضعف رغم ذلك.

تجميعها ، هذا يعمل:

let numbers n = seq { 1. .. 1./0. } |> Seq.take(n)

أشعر بأن seq.initinfinite هو الخيار الأفضل لك. الرمز أعلاه يبدو غريبا بالنسبة لي. (أو على الأقل استخدم double.positiveInfinity بدلاً من 1./0.)

للوهلة الأولى ، سيكون هناك خيار رائع أن يكون في اللغة مشغلًا لا حصر له مثل في Haskell: Seq {1 ..} المشكلة هي أنه سيعمل فقط مع SEQ ، لذلك أعتقد أن العمل الإضافي لدعم مشغلي Postfix هو لا يستحق ذلك لهذه الميزة وحدها.

خلاصة القول: في رأيي ، استخدم seq.initinfinite.

نصائح أخرى

أعتقد أن ما يلي هو الحل الأفضل للنطاقات اللانهائية في F#؛ من خلال وضع علامة على الوظيفة inline نحن نفعل أفضل من "اللانهاية المكتوبة ديناميكيًا" ، نحصل على نطاقات لا حصر لها من الناحية الهيكلية (تعمل مع int32 ، int64 ، bigint ، ... أي نوع يحتوي على عضو ثابت + التي تأخذ وسيطتين من نوعه الخاص وإرجاع قيمة من نوعه الخاص):

let inline infiniteRange start skip = 
    seq {
        let n = ref start
        while true do
            yield n.contents
            n.contents <- n.contents + skip
    }

//val inline infiniteRange :
//   ^a ->  ^b -> seq< ^a>
//    when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^a)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top