-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How would I phrase this flatten
func in MLStruct?
#2
Comments
Hi @metaleap. Thanks for your interest in this project! Here's how you implement your function in MLstruct: class Nil
class Cons[A]: { h: A; t: List[A] }
type List[A] = Cons[A] | Nil
def concat: List['a] -> List['a] -> List['a]
rec def concat x y = case x of
Nil -> y,
Cons -> Cons { h = x.h; t = concat x.t y }
rec def flatten x = case x of
Nil -> Nil{},
Cons -> concat (flatten x.h) (flatten x.t),
_ -> Cons { h = x; t = Nil{} } You can try it in the web demo or in the project's diff-tests, which yield the following output: class Nil
class Cons[A]: { h: A; t: List[A] }
type List[A] = Cons[A] | Nil
//│ Defined class Nil
//│ Defined class Cons[+A]
//│ Defined type alias List[+A]
def concat: List['a] -> List['a] -> List['a]
rec def concat x y = case x of
Nil -> y,
Cons -> Cons { h = x.h; t = concat x.t y }
//│ concat: List['a] -> List['a] -> List['a]
//│ = <missing implementation>
//│ 'a -> 't -> 't
//│ where
//│ 't :> Cons['A] & {h: 'h, t: 't}
//│ <: List['A]
//│ 'a <: #Cons & {h: 'h & 'A, t: 'a} | Nil
//│ <: concat:
//│ List['a] -> List['a] -> List['a]
//│ = [Function: concat1]
rec def flatten x = case x of
Nil -> Nil{},
Cons -> concat (flatten x.h) (flatten x.t),
_ -> Cons { h = x; t = Nil{} }
//│ flatten: 'a -> (Cons['h] & {t: Nil} | Nil | List['h])
//│ where
//│ 'a <: #Cons & {h: 'a, t: 'a} | Nil | 'h & ~#Cons & ~#Nil
//│ = [Function: flatten]
c1 = Cons { h = 123; t = Nil{} }
//│ c1: Cons[123] & {t: Nil}
//│ = Cons { h: 123, t: Nil {} }
flatten c1
//│ res: Cons[123] & {t: Nil} | Nil | List[123]
//│ = Cons { h: 123, t: Nil {} }
c2 = Cons { h = c1; t = c1 }
//│ c2: Cons[123 | Cons[123] & {t: Nil}] & {h: Cons[123] & {t: Nil}, t: Cons[123] & {t: Nil}}
//│ = Cons { h: Cons { h: 123, t: Nil {} }, t: Cons { h: 123, t: Nil {} } }
flatten c2
//│ res: Cons[123] & {t: Nil} | Nil | List[123]
//│ = Cons { h: 123, t: Cons { h: 123, t: Nil {} } } The main differences with Castagna's work is that:
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Having not (yet) laboured through your 2024 MLStruct Type Inference 181-pager, I still wanted to see in your web playground how the below function will be type-inferenced in MLStruct, ML-ish pseudocode taken from Castagna et al 2024: Polymorphic Type Inference for Dynamic Languages where I just found that very interesting case of a polymorphic function that's technically "just"
Any -> [Any]
but invites more specific typing in a intersection/union/negation-supported type-inferencing setup:Would you mind a quick transcription to MLStruct here I can paste into https://hkust-taco.github.io/mlstruct/ editor, so I can try it out? Many thanks in advance!
The text was updated successfully, but these errors were encountered: