O ile mogę powiedzieć, F # nie ma żadnego wsparcia dla typów egzystencjalnych. Tak więc szukam innego sposobu na wyrażenie mojego pomysłu.Wyrażanie typów egzystencjalnych w F #
Mam strukturę danych, a jej zawartość można interpretować na wiele różnych sposobów. W tym konkretnym przykładzie ja przypuszczam może być postrzegane jako int lub rzeczywistego:
type Packed = (* something sensible *) unit
type PackedType = | PackedInt
| PackedReal
let undefined<'a> : 'a = failwith "undefined"
let unpackInt : Packed -> int = undefined
let unpackReal : Packed -> real = undefined
let packInt : int -> Packed = undefined
let packReal : real -> Packed = undefined
gdzie real
jest czymś znaczącym, powiedzieć:
type real = int * int
let addReal : real -> real -> real = undefined
Teraz muszę funkcję addPacked : PackedType -> Packed -> Packed -> Packed
. Chciałbym go mieć ogólnie, to jest:
type NumberOp = [forall t] { opPack : 't -> Packed; opUnpack : Packed -> 't; opAdd : 't -> 't -> 't }
let getNumberOp (t : PackedType) =
match t with
| PackedInt -> { opPack = packInt; opUnpack = unpackInt; opAdd = (+) }
| PackedReal -> { opPack = packReal; opUnpack = unpackReal; opAdd = addReal }
let addPacked (t : PackedType) (a : Packed) (b : Packed) =
let { opPack = pack; opUnpack = unpack; opAdd = add } = getNumberOp t
pack <| add (unpack a) (unpack b)
Tutaj skończyło się NumberOp
będąc existetial. Pytam więc, czy istnieje inny sposób wyrażenia tego. Nie mogę zmienić funkcji Packed
, [un]pack*
i typu .
Znalazłem odpowiedź this. Stwierdza, że istnieje "dobrze znany wzorzec", ale tekst jest trudny do odczytania i nie mogłem go uruchomić.
Zobacz także http://stackoverflow.com/questions/15690053/impredicative-polymorphism-in-f –