This projectは実際にはsourceofquestionsです。シーケンス式と多相再帰はどのように連動しますか?
多相再帰について既に知っていて、それが特別なケースである理由を理解しています。したがって、F#には完全型アノテーションが必要です。
通常の機能のためには、いくつかのフィディリングが必要な場合がありますが、通常は正しくなります。現在、私は(作業中の)基本的なtoSeq
をより特殊な指のツリーに適応しようとしていますが、できません。
私の気持ちは、計算式の使用には関係があります。これは、凝縮作業バージョンです:
module ThisWorks =
module Node =
type Node<'a> =
| Node2 of 'a * 'a
| Node3 of 'a * 'a * 'a
let toList = function
| Node2(a, b) -> [a; b]
| Node3(a, b, c) -> [a; b; c]
module Digit =
type Digit<'a> =
| One of 'a
| Two of 'a * 'a
| Three of 'a * 'a * 'a
| Four of 'a * 'a * 'a * 'a
let toList = function
| One a -> [a]
| Two(a, b) -> [a; b]
| Three(a, b, c) -> [a; b; c]
| Four(a, b, c, d) -> [a; b; c; d]
module FingerTree =
open Node
open Digit
type FingerTree<'a> =
| Empty
| Single of 'a
| Deep of Digit<'a> * Lazy<FingerTree<Node<'a>>> * Digit<'a>
let rec toSeq<'a> (tree:FingerTree<'a>) : seq<'a> = seq {
match tree with
| Single single ->
yield single
| Deep(prefix, Lazy deeper, suffix) ->
yield! prefix |> Digit.toList
yield! deeper |> toSeq |> Seq.collect Node.toList
yield! suffix |> Digit.toList
| Empty ->()
}
私はコンパイルするために取得するために管理していない1本です:
module ThisDoesnt =
module Monoids =
type IMonoid<'m> =
abstract Zero:'m
abstract Plus:'m -> 'm
type IMeasured<'m when 'm :> IMonoid<'m>> =
abstract Measure:'m
type Size(value) =
new() = Size 0
member __.Value = value
interface IMonoid<Size> with
member __.Zero = Size()
member __.Plus rhs = Size(value + rhs.Value)
type Value<'a> =
| Value of 'a
interface IMeasured<Size> with
member __.Measure = Size 1
open Monoids
module Node =
type Node<'m, 'a when 'm :> IMonoid<'m>> =
| Node2 of 'm * 'a * 'a
| Node3 of 'm * 'a * 'a * 'a
let toList = function
| Node2(_, a, b) -> [a; b]
| Node3(_, a, b, c) -> [a; b; c]
module Digit =
type Digit<'m, 'a when 'm :> IMonoid<'m>> =
| One of 'a
| Two of 'a * 'a
| Three of 'a * 'a * 'a
| Four of 'a * 'a * 'a * 'a
let toList = function
| One a -> [a]
| Two(a, b) -> [a; b]
| Three(a, b, c) -> [a; b; c]
| Four(a, b, c, d) -> [a; b; c; d]
module FingerTree =
open Node
open Digit
type FingerTree<'m, 'a when 'm :> IMonoid<'m>> =
| Empty
| Single of 'a
| Deep of 'm * Digit<'m, 'a> * Lazy<FingerTree<'m, Node<'m, 'a>>> * Digit<'m, 'a>
let unpack (Value v) = v
let rec toSeq<'a> (tree:FingerTree<Size, Value<'a>>) : seq<'a> = seq {
match tree with
| Single(Value single) ->
yield single
| Deep(_, prefix, Lazy deeper, suffix) ->
yield! prefix |> Digit.toList |> List.map unpack
#if ITERATE
for (Value deep) in toSeq deeper do
^^^^^
yield deep
#else
yield! deeper |> toSeq |> Seq.collect (Node.toList >> List.map unpack)
^^^^^
#endif
yield! suffix |> Digit.toList |> List.map unpack
| Empty ->()
}
私が取得エラーメッセージが
エラータイプの不一致を語ります。 B
しかし '> > C - >配列<'
2-3フィンガーツリー<サイズ、値<を所与 -
2-3フィンガーツリー<サイズ、ノード<サイズ、値< '> > > >' を期待>
C型 'ノード<サイズ、値<' > > 'がタイプ'値< 'と一致しません。>'
そして、スクイブルは、toSeq
の再帰呼び出しに下線を引いている。
「より深い」タイプはNode
にカプセル化されており、作業コードでは後で解凍するだけです。しかし、ここでコンパイラは、私が解凍するチャンスを得る前に既に移動しています。 for (Value deep) in toSeq deeper do yield deep
を試しても同じ問題があります。
は、私はすでに、「ベース」その後本当ではない、試してみると、非常に似たエラーメッセージが表示されます。Tree
とSeq.map unpack
のtoSeq
を使用すること、すなわち、アウトの方法を持っています。
私はこのコードブレークをどのようにして修正できるのか不思議です。