This project은 실제로 나를 위해 sourceofquestions입니다.시퀀스 식과 다형성 재귀가 함께 어떻게 작동합니까?
나는 다형성 재귀에 대해 이미 배웠고 특별한 경우 인 이유를 이해하고 있으며 따라서 F #에는 전체 형식 주석이 필요합니다.
정규 기능의 경우 약간의 경매가 필요할 수 있지만 일반적으로 올바르게 처리됩니다. 이제는 (작동하는) 기본 toSeq
을보다 특수화 된 손가락 트리에 적용하려고하지만 할 수 없습니다.
제 생각에 계산 표현식을 사용하는 것과 관련이 있습니다.
이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 ->()
}
내가 오류 메시지가
오류 유형 불일치를 말한다 :
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 ->() }
내가 컴파일 얻을 관리하지 않는 한이 있습니다 :이 응축 된 작동 버전입니다 .
b를하지만
FingerTree < 크기, 값 < '> > C - 서열 < >'주어 - '> > > >'는
FingerTree < 크기, 노드 < 크기, 값 <을 기대 C를 >
형식 '노드 < 크기, 값 <'a > > '이'값 < '형식과 일치하지 않습니다. >'
그리고 squiggles는 toSeq
의 재귀 호출에 밑줄을 긋습니다.
"더 깊은"유형이 Node
에 캡슐화되어 있으며 작업 코드에서 나중에 압축을 풀었습니다. 하지만 여기서 컴파일러는 이미 압축을 풀기 전에 이동합니다. for (Value deep) in toSeq deeper do yield deep
을 시도하면 같은 문제가 발생합니다.
는 이미 즉 "기본"이후 사실이 아니라면 비슷한 오류 메시지가 나타납니다.Tree
및 Seq.map unpack
의 toSeq
를 사용하여, 밖으로 방법이있다.
나는이 코드를 어떻게 만들지, 어떻게 고칠 수 있는지 궁금합니다. toSeq
는 일부 'a
에 대한 유형 FingerTree<Size, Value<'a>>
의 값을 적용 할 수 있지만 호환되지 않는 대신 유형 FingerTree<Size,Node<Size,Value<'a>>>
의 값에 호출하려는 :