मैं Hinze द्वारा (हास्केल) पत्र में वर्णित के रूप में 2-3 उंगली के पेड़ के साथ चारों ओर खेलना चाहते थे लागू करने (यह भी देखें इस blog)। >प्रकार त्रुटि जब उंगली पेड़
उम्मीद एक FingerTree < 'एक> लेकिन एक FingerTree दिया:
type Node<'a> = | Node2 of 'a * 'a | Node3 of 'a * 'a * 'a static member OfList = function | [a; b] -> Node2(a, b) | [a; b; c] -> Node3(a, b, c) | _ -> failwith "Only lists of length 2 or 3 accepted!" member me.ToList() = match me with | Node2(a, b) -> [a; b] | Node3(a, b, c) -> [a; b; c] type Digit<'a> = | One of 'a | Two of 'a * 'a | Three of 'a * 'a * 'a | Four of 'a * 'a * 'a * 'a static member OfList = function | [a] -> One(a) | [a; b] -> Two(a, b) | [a; b; c] -> Three(a, b, c) | [a; b; c; d] -> Four(a, b, c, d) | _ -> failwith "Only lists of length 1 to 4 accepted!" member me.ToList() = match me with | One a -> [a] | Two(a, b) -> [a; b] | Three(a, b, c) -> [a; b; c] | Four(a, b, c, d) -> [a; b; c; d] member me.Append x = match me with | One a -> Two(a, x) | Two(a, b) -> Three(a, b, x) | Three(a, b, c) -> Four(a, b, c, x) | _ -> failwith "Cannot prepend to Digit.Four!" member me.Prepend x = match me with | One a -> Two(x, a) | Two(a, b) -> Three(x, a, b) | Three(a, b, c) -> Four(x, a, b, c) | _ -> failwith "Cannot prepend to Digit.Four!" [<NoComparison>] [<NoEquality>] type FingerTree<'a> = | Empty | Single of 'a | Deep of Digit<'a> * FingerTree<Node<'a>> * Digit<'a> type Digit<'a> with member me.Promote() = match me with | One a -> Single a | Two(a, b) -> Deep(One a, Empty, One b) | Three(a, b, c) -> Deep(One a, Empty, Two(b, c)) | Four(a, b, c, d) -> Deep(Two(a, b), Empty, Two(c, d)) type View<'a> = Nil | View of 'a * FingerTree<'a>
अब मैं सिर्फ
viewl
समारोह काम कर नहीं मिल सकता है, यह एक प्रकार मेल नहीं खाता के बारे में शिकायत। जब '' एक 'और' नोड < 'एक>' FingerTree एकीकृतजिसके परिणामस्वरूप प्रकार अनंत होगा।
let rec viewl : FingerTree<'a> -> View<'a> = function
| Empty -> Nil
| Single x -> View(x, Empty)
| Deep(One x, deeper(*:FingerTree<'a>/FingerTree<Node<'a>>*), suffix) ->
let rest =
match viewl deeper with
| Nil ->
suffix.Promote()
| View (node(*:Node<'a>*), rest) ->
let prefix = node.ToList() |> Digit<_>.OfList
Deep(prefix, rest, suffix)
View(x, rest)
| Deep(prefix, deeper, suffix) ->
match prefix.ToList() with
| x::xs ->
View(x, Deep(Digit<_>.OfList xs, deeper, suffix))
| _ -> failwith "Impossible!"
मैं prepend
में से पहले इस त्रुटि थी, लेकिन समारोह पर पूरा प्रकार की जानकारी जोड़कर इसे हल करने में सक्षम था।
// These three/four type annotations solved the problem.
let rec prepend<'a> (a:'a) : FingerTree<'a> -> FingerTree<'a> = function
| Empty -> Single a
| Single b -> Deep(One a, Empty, One b)
| Deep(Four(b, c, d, e), deeper, suffix) ->
Deep(Two(a, b), prepend (Node3(c, d, e)) deeper, suffix)
| Deep(prefix, deeper, suffix) ->
Deep(prefix.Prepend a, deeper, suffix)
viewl
के लिए यह पर्याप्त नहीं लगता है, तो मैं भी समारोह के बीच (टिप्पणी के लिए लग रही है) में प्रकार जोड़ने की कोशिश की। यह काम नहीं किया।
मैं तरह की त्रुटि को समझते हैं और यह कहाँ से आ रहा है। क्या कोई मुझे बता सकता है कि यह कैसे काम कर रहा है? आईएमएचओ, यह संभव होना चाहिए, क्योंकि अन्यथा prepend
भी संकलित नहीं होगा। शायद this की तरह एक चाल मदद करता है? (हालांकि इसे समझ में नहीं आता)।
पुनश्च: मैं भी कोड FsSnip पर ब्राउज़र में चारों ओर खेलने के लिए डाल दिया।
दीप 2 आइटम एक 'FingerTree> है' और 'viewl' लेता है एक' FingerTree <'a> 'कि तात्पर्य है कि' A' एक 'नोड <'a> होना चाहिए 'इसलिए यह त्रुटि संदेश –
Sehnsucht
@Sehnsucht नहीं कर सकता है: लेकिन किसी भी' प्रीपेन्ड 'एनोटेशन को हटाते समय मुझे एक ही त्रुटि मिलती है। और मैं शर्त लगाता हूं कि वही तर्क वहां रहता है, क्योंकि हर पेड़ के स्तर में वास्तव में अपना स्वयं का प्रकार होता है। लेकिन प्रीपेन्ड के लिए आप इसे काम कर सकते हैं। – primfaktor