-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
196 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# FSTan Guide | ||
|
||
|
||
Typeclasses | ||
============= | ||
|
||
|
||
Typeclassess are achived through abstract classes, which makes it works perfect for both subtypeclassing and default implementations. | ||
|
||
If some type is constructed with a type constructor, you can implement `show` class for it. | ||
|
||
Let's have a look at how to write a `show` class and use it in polymorphism functions and even operators. | ||
|
||
|
||
```FSharp | ||
open FSTan.HKT | ||
// define a simple typeclass | ||
[<AbstractClass>] | ||
type show<'s>() = | ||
abstract member show<'a> : hkt<'s, 'a> -> string | ||
// I have a typeclass, | ||
// I have 2 datatypes, | ||
// Oh! | ||
// Polymorphism! | ||
let show<'a, 's when 's :> show<'s>> = getsig<'s>.show<'a> | ||
type myData1<'a> = // define datatype | ||
| A | B | C | ||
interface hkt<MyTypeCons1, 'a> | ||
and MyTypeCons1() = | ||
// define type constructor | ||
// in F#, we don't really have this, but | ||
// we can leverage a signature type(yes, this is just a signature) | ||
// and `hkt`(check FSTan.HKT, not magic at all) | ||
// to fully simulate a type constructor. | ||
inherit show<MyTypeCons1>() with | ||
override si.show a = | ||
// This conversion can absolutely succeed | ||
// for there is only one datatype which | ||
// interfaces hkt<MyTypeCons1, 'a> | ||
let a = a :?> _ myData1 | ||
sprintf "%A" a | ||
type myData2<'a> = // define datatype | ||
| I of int | ||
| S of string | ||
interface hkt<MyTypeCons2, 'a> | ||
and MyTypeCons2() = | ||
// define type constructor | ||
// in F#, we don't really have this, but | ||
// we can leverage a signature type(yes, this is just a signature) | ||
// and `hkt`(check FSTan.HKT, not magic at all) | ||
// to fully simulate a type constructor. | ||
inherit show<MyTypeCons2>() with | ||
override si.show a = | ||
let a = a :?> _ myData2 | ||
match a with | ||
| I a -> sprintf "isInt %d" a | ||
| S a -> sprintf "isStr %s" a | ||
``` | ||
|
||
|
||
Subtypeclassing | ||
============= | ||
|
||
Check https://github.com/thautwarm/FSTan/blob/master/FSTan/Functor.fs. | ||
|
||
|
||
Higher kined types | ||
================== | ||
|
||
A signature type to represent a type constructor in FSTan: | ||
|
||
```FSharp | ||
type Sig = .. | ||
let test_hkt<'a, 'b, 'c> (f: hkt<'a, 'b>) : hkt<'b, 'c> = | ||
/// impl | ||
``` | ||
|
||
In terms of above snippet, if `c` is a concrete type, then `'a` is kinded of `* -> * -> *`, as well as `b` is kinded of `* -> *`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Learn more about F# at http://fsharp.org | ||
|
||
open System | ||
|
||
open FSTan.HKT | ||
|
||
// define a simple typeclass | ||
[<AbstractClass>] | ||
type show<'s>() = | ||
abstract member show<'a> : hkt<'s, 'a> -> string | ||
|
||
let show<'a, 's when 's :> show<'s>> = getsig<'s>.show<'a> | ||
|
||
type myData1<'a> = // define datatype | ||
| A | B | C | ||
interface hkt<MyTypeCons1, 'a> | ||
|
||
and MyTypeCons1() = | ||
// define type constructor | ||
// in F#, we don't really have this, but | ||
// we can leverage a signature type(yes, this is just a signature) | ||
// and `hkt`(check FSTan.HKT, not magic at all) | ||
// to fully simulate a type constructor. | ||
inherit show<MyTypeCons1>() with | ||
override si.show a = | ||
// This conversion can absolutely succeed | ||
// for there is only one datatype which | ||
// interfaces hkt<MyTypeCons1, 'a> | ||
let a = a :?> _ myData1 | ||
|
||
sprintf "%A" a | ||
|
||
|
||
type myData2<'a> = // define datatype | ||
| I of int | ||
| S of string | ||
interface hkt<MyTypeCons2, 'a> | ||
and MyTypeCons2() = | ||
// define type constructor | ||
// in F#, we don't really have this, but | ||
// we can leverage a signature type(yes, this is just a signature) | ||
// and `hkt`(check FSTan.HKT, not magic at all) | ||
// to fully simulate a type constructor. | ||
inherit show<MyTypeCons2>() with | ||
override si.show a = | ||
let a = a :?> _ myData2 | ||
match a with | ||
| I a -> sprintf "isInt %d" a | ||
| S a -> sprintf "isStr %s" a | ||
|
||
|
||
let test() = | ||
let s1 = show <| I 32 | ||
let s2 = show <| S "123" | ||
let s3 = show A | ||
let s4 = show B | ||
printfn "%s\n%s\n%s\n%s" s1 s2 s3 s4 | ||
|
||
[<EntryPoint>] | ||
let main argv = | ||
test() | ||
0 // return an integer exit code |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>netcoreapp2.1</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="Program.fs" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\FSTan\FSTan.fsproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |