将更高的kinded类型(monads!)嵌入到无类型的lambda演算中

时间:2012-01-19 11:17:04

标签: haskell functional-programming monads lambda-calculus untyped-variables

可以通过高阶函数对无类型lambda演算中的各种类型进行编码。

Examples:
zero  = λfx.      x
one   = λfx.     fx
two   = λfx.   f(fx)
three = λfx. f(f(fx))
etc

true  = λtf. t
false = λtf. f

tuple = λxyb. b x y
null  = λp. p (λxy. false)

我想知道是否有任何研究已经用于嵌入其他不太常规的类型。如果有一些定理断言可以嵌入任何类型,那将是很棒的。也许有限制,例如只能嵌入类型*。

如果确实可以表示不太常规的类型,那么看一个例子真是太棒了。我特别热衷于看看monad类型成员的样子。

3 个答案:

答案 0 :(得分:17)

可以表示您想要的任何类型。但由于monadic操作对于每种类型都有不同的实现方式,因此 可能只需编写一次>>=并使其适用于每个实例。

但是,可以编写依赖于类型类实例的证据的泛型函数。考虑e这里是一个元组,fst e包含“绑定”定义,snd e包含“返回”定义。

bind = λe. fst e    -- after applying evidence, bind looks like λmf. ___
return = λe. snd e  -- after applying evidence, return looks like λx. ___

fst = λt. t true
snd = λt. t false

-- join x = x >>= id
join = λex. bind e x (λz. z)

-- liftM f m1 = do { x1 <- m1; return (f x1) }
-- m1 >>= \x1 -> return (f x1)
liftM = λefm. bind e m (λx. return e (f x))

然后,您必须为Monad的每个实例定义“证据元组”。请注意我们定义bindreturn的方式:它们就像我们定义的其他“通用”Monad方法一样:首先必须给出Monad-ness的证据 ,然后它们按预期运行。

我们可以将Maybe表示为一个带有2个输入的函数,第一个是一个函数,如果它是Just x则执行,第二个是要替换它的值,如果它是Nothing。

just = λxfz. f x
nothing = λfz. z

-- bind and return for maybes
bindMaybe = λmf. m f nothing
returnMaybe = just

maybeMonadEvidence = tuple bindMaybe returnMaybe

列表类似,表示List作为其折叠功能。因此,列表是一个带有2个输入的函数,“cons”和“empty”。然后它会在列表中执行foldr myCons myEmpty

nil = λcz. z
cons = λhtcz. c h (t c z)

bindList = λmf. concat (map f m)
returnList = λx. cons x nil

listMonadEvidence = tuple bindList returnList

-- concat = foldr (++) []
concat = λl. l append nil

-- append xs ys = foldr (:) ys xs
append = λxy. x cons y

-- map f = foldr ((:) . f) []
map = λfl. l (λx. cons (f x)) nil

Either也很简单。将任一类型表示为具有两个函数的函数:如果它是Left则应用一个函数,如果它是Right则应用另一个函数。

left = λlfg. f l
right = λrfg. g r

-- Left l >>= f = Left l
-- Right r >>= f = f r
bindEither = λmf. m left f
returnEither = right

eitherMonadEvidence = tuple bindEither returnEither

不要忘记,函数自己 (a ->)形成一个monad。 lambda演算中的所有内容都是函数......所以......不要太考虑它。 ;)直接来自Control.Monad.Instances

的来源
-- f >>= k = \ r -> k (f r) r
bindFunc = λfkr. k (f r) r
-- return = const
returnFunc = λxy. x

funcMonadEvidence = tuple bindFunc returnFunc

答案 1 :(得分:12)

您正在将类型级别与值级别混合。在无类型的lambda演算中,没有monad。可以有monadic操作(值级别),但不能使用monad(类型级别)。但是,操作本身可以是相同的,因此您不会失去任何表达能力。所以问题本身并没有多大意义。

答案 2 :(得分:1)

好吧,我们已经有了元组和布尔值,因此我们可以代表Either,依次代表任何非递归和类型:

type Either a b = (Bool, (a, b))
type Maybe a    = Either () a

而且可能是Monad类型的成员。翻译为lambda表示法留作练习。