https://github.com/thautwarm/fstan
Higher abstraction infrastructures in F#(ad-hoc polymorphism, subtypeclassing, monad, hkt...), exactly what we've dreamed about for so long
https://github.com/thautwarm/fstan
functional-programming higher-kinded-types monad monoids subtypeclassing typeclasses
Last synced: 2 months ago
JSON representation
Higher abstraction infrastructures in F#(ad-hoc polymorphism, subtypeclassing, monad, hkt...), exactly what we've dreamed about for so long
- Host: GitHub
- URL: https://github.com/thautwarm/fstan
- Owner: thautwarm
- License: apache-2.0
- Created: 2018-12-26T08:09:10.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2019-06-02T01:29:04.000Z (over 6 years ago)
- Last Synced: 2025-06-09T06:03:53.251Z (5 months ago)
- Topics: functional-programming, higher-kinded-types, monad, monoids, subtypeclassing, typeclasses
- Language: F#
- Homepage:
- Size: 76.2 KB
- Stars: 43
- Watchers: 5
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# FSTan
Exactly a full-featured and practical implementation typeclasses and higher kinded types in F#.
For manuals check [Guide.md](https://github.com/thautwarm/FSTan/blob/master/Guide.md), where you'll be told how to use these concise typeclasses, higher kinded types and constraints.
## Motivation and Features
There are also other similar implementations in FSharp like `Higher` and `FSharpPlus`, but they're not able to provide all the features listed below, which motivate me to create a better one:
- Support instance resolution.
- Support ad-hoc polymorphism.
- Support to create a typeclass and add constraints to it.
- Support subtypeclassing.
- Support to directly access type constructor.
- Support default implementations for typeclass.
- All above operations are quite lightweighted and not implemented in a magic way.Yes, exactly, it's a what many and I have dreamed about for so long.
## Limitation
1. The performance might hurt in some scenarios, for each the datatype works with
higher kinded types have to be upcasted to an unique abstract class, for instance,
`maybe<'a>` has to be casted to `hkt`.2. For some builtin datatypes cannot be interfaced with `hkt`, an extra wrapper class is
required to work with higher kined types.For instance, interface type `listData<'a>` is required for the builtin `List<'a>`.
You can use `wrap` and `unwrap` to transform datatypes from `List<'a>` to `hkt,'a>`, vice versa.
```FSharp
module List' = List
type List'<'a> = List<'a>type mkList<'L>() =
inherit monad>()
static member wrap<'a> (x : List'<'a>): hkt, 'a> =
{wrap = x} :> _
static member unwrap<'a> (x : hkt, 'a>): List'<'a> =
(x :?> _).wrapdefault si.bind<'a, 'b> (m: hkt, 'a>) (k: 'a -> hkt, 'b>): hkt, 'b> =
wrap <| List'.collect (unwrap << k) (unwrap m)default si.pure'<'a> (a: 'a): hkt, 'a> = wrap <| [a]
interface show> with
member si.show (x: hkt, 'a>) =
let x = unwrap x
x.ToString()and listData<'L, 'a> =
{wrap : List'<'a>}
interface hkt, 'a>// create a concrete List type
type ListSig() =
// default implements following type classes:
// - monad (functor and applicative are implemented simultaneously)
// - showinherit mkList()
type list<'a> = hkt, 'a>let test() =
let listm: _ list = Do {
let! x = wrap [1, 2, 3]
wrap [x]
}
// listm : resolved to be listlet f (x: int) : string = ""
fmap f listm
// return value is resolved to be list
```
3. Cannot implement instance for datatypes that are not constructed by a type constructor.
For instance, you cannot implement any typeclass for all primitives types like integers, floats and so on, unless you wrap them with an `Identity` type constructor.