[英]Embedding higher kinded types (monads!) into the untyped lambda calculus
通過高階函數可以在無類型的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類型類的成員的外觀。
幾乎可以代表您想要的任何類型。 但由於一元操作對每種類型的實現方式不同,它是不可能寫>>=
一次,有它的每個實例工作。
但是,您可以編寫依賴於類型類實例證據的泛型函數。 此處將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的每個實例定義一個“證據元組”。 請注意,我們定義的bind
和return
:它們的工作方式與我們定義的其他“通用” 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
列表相似,將列表表示為其折疊功能。 因此,列表是一個需要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 ->)
a- (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
您正在將類型級別與值級別混合在一起。 在無類型的lambda演算中,沒有單子。 可以有單子運算(值級別),但不能有單子運算(類型級別)。 但是,操作本身可以相同,因此您不會失去任何表達能力。 因此,問題本身並沒有任何意義。
好了,我們已經有元組和布爾值,因此我們可以表示Either
而表示基於該值的任何非遞歸和類型:
type Either a b = (Bool, (a, b))
type Maybe a = Either () a
也許是Monad類型類的成員。 練習轉換為lambda表示法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.