1 people like it.
Like the snippet!
HList with Mapper and Folder
Extended from: http://www.fssnip.net/d2
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
|
type HList = interface end
and HNil = HNil with
static member inline (|*|) (f, HNil) = f $ HNil
static member inline Map (m, HNil) = HNil
interface HList
and HCons<'a, 'b when 'b :> HList> = HCons of 'a * 'b with
static member inline (|*|) (f, HCons(x, xs)) = f $ HCons(x, xs)
interface HList
let inline head (HCons(h,t)) = h
let inline tail (HCons(h,t)) = t
type Peano = interface end
and Zero = Zero with
static member inline (|*|) (f, Zero) = f $ Zero
interface Peano
and Succ<'a when 'a :> Peano> = Succ of 'a with
static member inline (|*|) (f, Succ(x)) = f $ Succ(x)
interface Peano
type Bool = interface end
and True = True with
interface Bool
and False = False with
interface Bool
let inline (^+^) head tail = HCons(head, tail)
// Examples
type Append = Append with
static member ($) (Append, HNil) = id
static member inline ($) (Append, HCons(x, xs)) = fun list ->
HCons (x, (Append |*| xs) list)
type ZeroMapper = ZeroMapper with
static member ($) (ZeroMapper, HNil) = HNil
static member inline ($) (ZeroMapper, HCons(x : string, xs)) = HCons("", ZeroMapper |*| xs)
static member inline ($) (ZeroMapper, HCons(x : int, xs)) = HCons(0, ZeroMapper |*| xs)
type Length = Length with
static member ($) (Length, HNil) = Zero
static member inline ($) (Length, HCons(x, xs)) = Succ (Length |*| xs)
type Count = Count with
static member ($) (Count, HNil) = 0
static member inline ($) (Count, HCons(x, xs)) = 1 + (Count |*| xs)
let first = 1 ^+^ '1' ^+^ HNil
let second = "1" ^+^ true ^+^ HNil
let third = "one" ^+^ 123 ^+^ HNil
// result : HCons<int,HCons<char,HCons<string,HCons<bool,HNil>>>>
let result = (Append $ first) second // HCons (1,HCons ('1',HCons ("1",HCons (true,HNil))))
ZeroMapper $ third // HCons<string,HCons<int,HNil>> = HCons ("",HCons (0,HNil))
ZeroMapper $ second // type error, no char version of ZeroMapper defined
tail third // HCons (123,HNil)
(tail >> tail) third // HNil
(tail >> tail >> tail) third // compiler error
// length : Succ<Succ<Succ<Succ<Zero>>>>
let length = Length $ result // Succ (Succ (Succ (Succ Zero)))
let count = Count $ result // 4
|
Multiple items
union case HNil.HNil: HNil
--------------------
type HNil =
| HNil
interface HList
static member Map : m:'a * HNil:HNil -> HNil
static member ( |*| ) : f:'a * HNil:HNil -> '_arg6 (requires member ( $ ))
Full name: Script.HNil
val f : 'a (requires member ( $ ))
Multiple items
static member HNil.Map : m:'a * HNil:HNil -> HNil
Full name: Script.HNil.Map
--------------------
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IEnumerable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
member Add : key:'Key * value:'Value -> Map<'Key,'Value>
member ContainsKey : key:'Key -> bool
override Equals : obj -> bool
member Remove : key:'Key -> Map<'Key,'Value>
...
Full name: Microsoft.FSharp.Collections.Map<_,_>
--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val m : 'a
type HList
Full name: Script.HList
Multiple items
union case HCons.HCons: 'a * 'b -> HCons<'a,'b>
--------------------
type HCons<'a,'b (requires 'b :> HList)> =
| HCons of 'a * 'b
interface HList
static member ( |*| ) : f:'a0 * HCons<'b1,'c> -> '_arg9 (requires member ( $ ) and 'c :> HList)
Full name: Script.HCons<_,_>
val f : 'a (requires member ( $ ) and 'c :> HList)
val x : 'b
val xs : #HList
val head : HCons<'a,#HList> -> 'a
Full name: Script.head
val h : 'a
val t : #HList
val tail : HCons<'a,'b> -> 'b (requires 'b :> HList)
Full name: Script.tail
type Peano
Full name: Script.Peano
Multiple items
union case Zero.Zero: Zero
--------------------
type Zero =
| Zero
interface Peano
static member ( |*| ) : f:'a * Zero:Zero -> '_arg5 (requires member ( $ ))
Full name: Script.Zero
Multiple items
union case Succ.Succ: 'a -> Succ<'a>
--------------------
type Succ<'a (requires 'a :> Peano)> =
| Succ of 'a
interface Peano
static member ( |*| ) : f:'a0 * Succ<'b> -> '_arg8 (requires member ( $ ) and 'b :> Peano)
Full name: Script.Succ<_>
val f : 'a (requires member ( $ ) and 'b :> Peano)
val x : #Peano
type Bool
Full name: Script.Bool
Multiple items
union case True.True: True
--------------------
type True =
| True
interface Bool
Full name: Script.True
type False =
| False
interface Bool
Full name: Script.False
Multiple items
union case False.False: False
--------------------
type False =
| False
interface Bool
Full name: Script.False
val head : 'a
val tail : #HList
Multiple items
union case Append.Append: Append
--------------------
type Append =
| Append
static member ( $ ) : Append:Append * HNil:HNil -> ('a -> 'a)
static member ( $ ) : Append:Append * HCons<'a,'b> -> ('c -> HCons<'a,'d>) (requires 'b :> HList and member ( |*| ) and 'd :> HList)
Full name: Script.Append
val id : x:'T -> 'T
Full name: Microsoft.FSharp.Core.Operators.id
val x : 'a
val xs : 'b (requires 'b :> HList and member ( |*| ) and 'd :> HList)
Multiple items
val list : 'c
--------------------
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
Multiple items
union case ZeroMapper.ZeroMapper: ZeroMapper
--------------------
type ZeroMapper =
| ZeroMapper
static member ( $ ) : ZeroMapper:ZeroMapper * HNil:HNil -> HNil
static member ( $ ) : ZeroMapper:ZeroMapper * HCons<string,'b> -> HCons<string,'_arg9> (requires 'b :> HList and member ( |*| ) and '_arg9 :> HList)
static member ( $ ) : ZeroMapper:ZeroMapper * HCons<int,'a> -> HCons<int,'_arg12> (requires 'a :> HList and member ( |*| ) and '_arg12 :> HList)
Full name: Script.ZeroMapper
val x : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
val xs : 'b (requires 'b :> HList and member ( |*| ) and '_arg9 :> HList)
val x : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val xs : 'a (requires 'a :> HList and member ( |*| ) and '_arg12 :> HList)
Multiple items
union case Length.Length: Length
--------------------
type Length =
| Length
static member ( $ ) : Length:Length * HNil:HNil -> Zero
static member ( $ ) : Length:Length * HCons<'a,'b> -> Succ<'_arg7> (requires 'b :> HList and member ( |*| ) and '_arg7 :> Peano)
Full name: Script.Length
val xs : 'b (requires 'b :> HList and member ( |*| ) and '_arg7 :> Peano)
Multiple items
union case Count.Count: Count
--------------------
type Count =
| Count
static member ( $ ) : Count:Count * HNil:HNil -> int
static member ( $ ) : Count:Count * HCons<'a,'b> -> int (requires 'b :> HList and member ( |*| ))
Full name: Script.Count
val xs : 'b (requires 'b :> HList and member ( |*| ))
val first : HCons<int,HCons<char,HNil>>
Full name: Script.first
val second : HCons<string,HCons<bool,HNil>>
Full name: Script.second
val third : HCons<string,HCons<int,HNil>>
Full name: Script.third
val result : HCons<int,HCons<char,HCons<string,HCons<bool,HNil>>>>
Full name: Script.result
val length : Succ<Succ<Succ<Succ<Zero>>>>
Full name: Script.length
val count : int
Full name: Script.count
More information