Haskell 广义多参数函数提升的类型类技巧

Haskell 广义多参数函数提升的类型类技巧,haskell,dsl,typeclass,lifting,Haskell,Dsl,Typeclass,Lifting,我想将Haskell函数提升到高阶lambda演算编码中。这几乎是从Oleg的类型化无标记最终编码中一字不差地提取出来的 class Lam r where emb :: a -> r a (^) :: r (r a -> r a) -> (r a -> r a) lam :: (r a -> r a) -> r (r a -> r a) instance Lam Identity where emb = Identity f

我想将Haskell函数提升到高阶lambda演算编码中。这几乎是从Oleg的类型化无标记最终编码中一字不差地提取出来的

class Lam r where
  emb :: a -> r a
  (^) :: r (r a -> r a) -> (r a -> r a)
  lam :: (r a -> r a) -> r (r a -> r a)

instance Lam Identity where
  emb   = Identity
  f ^ x = f >>= ($ x)
  lam f = return (f . return =<<) -- call-by-value

 eval = runIdentity
不过,这是很多陈词滥调。我想创建一个通用的提升函数,它适用于任何算术函数。我觉得可以使用类似于
Printf
PrintfType
固定向量
Cont
类型。我可以使用类型函数指定所需的内容

type family   Low    h      o
type instance Low    ()     o =   o
type instance Low    (a, h) o =   a ->    Low    h o

type family   Lift r h      o
type instance Lift r ()     o =   o
type instance Lift r (a, h) o = r a -> r (Lift r h o)

class Emb r h o where
  embed :: Low h o -> r (Lift r h o)

instance ( Lam r ) => Emb r () o where
  embed = emb

instance ( Lam r, Applicative r, Emb r h o ) => Emb r (a, h) o where
  embed = ?
但是通过这种方法,我陷入了困境,通常是由于注入性问题。我能够用一个新类型包装器和作用域类型变量的真正可怕的组合来解析注入性,但它实际上从未进行过类型检查


这可以用Haskell表达吗?

您可能想看看 以无标签的最终风格。诀窍是在对象语言中泛化箭头类型。事实上我们经常使用Haskell's 对象语言中函数类型(要嵌入)的类型构造函数
->
是一种巧合和方便。通常,对象函数不会简单地映射到Haskell函数。参考文章中的代码包含ESymantics

-- How to interpret arrows and other types
type family Arr (repr :: * -> *) (a :: *) (b :: *) :: *

class ESymantics repr where
    int :: Int  -> repr Int
    add :: repr Int  -> repr Int -> repr Int

    lam :: (repr a -> repr b) -> repr (Arr repr a b)
    app :: repr (Arr repr a b) -> repr a -> repr b
现在,我们有足够的自由根据特定的报告来解释Arr。引用的文章为CPS实例解释Arr


编辑:事实证明,我们可以达到同样的效果——重新定义对象语言箭头的含义——而不引入Arr类型(及其内射性问题)和ESemantics。上面链接到普通和一次性CPS转换,显示了使用标准语义并重新解释函数类型构造函数含义的新代码。不再存在任何注入性问题。

我不知道答案,但下一个链接可能会有所帮助:我昨晚查看了这个链接,发现它提供了很多信息,但我需要找出如何最好地处理类型族的非注入性问题。我认为我通常对Haskell arrows将坚持使用对象语言表示的期望过高。感谢您的回复!
-- How to interpret arrows and other types
type family Arr (repr :: * -> *) (a :: *) (b :: *) :: *

class ESymantics repr where
    int :: Int  -> repr Int
    add :: repr Int  -> repr Int -> repr Int

    lam :: (repr a -> repr b) -> repr (Arr repr a b)
    app :: repr (Arr repr a b) -> repr a -> repr b