haskell - 将更高种类的类型(单子(monad)!)嵌入到无类型的 lambda 演算中

标签 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)

我想知道是否有任何研究涉及嵌入其他不太传统的类型。如果有某个定理断言可以嵌入任何类型,那就太好了。也许有限制,例如只能嵌入 kind * 的类型。

如果确实可以表示不太常规的类型,那么看到一个例子就太好了。我特别想看看 monad 类型类的成员是什么样子的。

最佳答案

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

但是,您可以编写依赖于类型类实例的证据的泛型函数。将这里的 e 视为一个元组,其中 fst e 包含“bind”定义,而 snd e 包含“return”定义。

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 方法:首先必须给它们提供证据 em> Monad-ness,然后它们按预期运行。

我们可以将Maybe表示为一个接受2个输入的函数,第一个是如果它是Just x则要执行的函数,第二个是要替换的值如果它是什么都没有的话。

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

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

maybeMonadEvidence = tuple bindMaybe returnMaybe

列表类似,将列表表示为它的折叠函数。因此,列表是一个需要 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

关于haskell - 将更高种类的类型(单子(monad)!)嵌入到无类型的 lambda 演算中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8925103/

相关文章:

haskell - 如何在 WAI/scotty 中记录整个 HTTP 请求?

list - 如何隐藏 [] (或一般 [] )的 Monad 实例?

haskell - 如何调用部分未嵌套的变压器?

scala - 如何命名包裹在 Monad 中的变量?

objective-c - 如何在 Objective-C 中编写 lambda 方法?

Ruby Map/Reduce 函数必须高效吗?

Haskell:FRP react 性 Parsec?

haskell - react 香蕉中的行为

xml - Haskell RSS、邮件和 XML 库选择

language-agnostic - 在纯函数式语言中调用函数和实例化对象之间有关系吗?