Note that there are some explanatory texts on larger screens.

plurals
  1. POTyped expression parser
    primarykey
    data
    text
    <p>I'm trying to create a typed expression parser in Haskell, which works great so far, but I'm currently struggling to implement higher order functions. I've boiled the problem down to a simple example:</p> <pre class="lang-hs prettyprint-override"><code>{-# LANGUAGE TypeFamilies,GADTs,FlexibleContexts,RankNTypes #-} -- A function has an argument type and a result type class Fun f where type FunArg f type FunRes f -- Expressions are either constants of function applications data Expr a where Const :: a -&gt; Expr a App :: Fun f =&gt; f -&gt; FunArg f -&gt; Expr (FunRes f) -- A very simple function data Plus = Plus -- Which takes two integer expressions and returns an integer expression instance Fun Plus where type FunArg Plus = (Expr Int,Expr Int) type FunRes Plus = Int -- A more complicated function which lifts a function to lists (like in haskell) data Map f r = Map f -- For this we need the concept of lifting function arguments: class Liftable a where type LiftRes a -- A singleton argument is lifted by changing the expression type from a to [a] instance Liftable (Expr a) where type LiftRes (Expr a) = Expr [a] -- Two function arguments are lifted by lifting each argument instance (Liftable a,Liftable b) =&gt; Liftable (a,b) where type LiftRes (a,b) = (LiftRes a,LiftRes b) -- Now we can declare a function instance for Map instance (Fun f,Liftable (FunArg f),r ~ LiftRes (FunArg f)) =&gt; Fun (Map f r) where type FunArg (Map f r) = r type FunRes (Map f r) = [FunRes f] -- Now a parser for functions: parseFun :: [String] -&gt; (forall f. Fun f =&gt; f -&gt; a) -&gt; a -- The parser for the plus function is easy: parseFun ["plus"] f = f Plus -- But the parser for map is not possible: parseFun ("map":sym) f = parseFun sym (\fun -&gt; f (Map fun)) </code></pre> <p>The problem seems to be that there is no way to convince the type checker that every LiftRes is itself Liftable, because recursive class declarations are forbidden.</p> <p>My question is: How do I make this work? Are there other examples of typed expression parsers from which I could take hints?</p> <p><strong>EDIT:</strong> It seems that <a href="https://stackoverflow.com/questions/14133121/can-i-constrain-a-type-family">this discussion about type family constraints</a> seems to be very related. However, I fail to make their solution work in my case, maybe someone can help with that?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload