簡體   English   中英

將更高種類的類型(monads)嵌入到未類型化的lambda演算中

[英]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的每個實例定義一個“證據元組”。 請注意,我們定義的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

列表相似,將列表表示為其折疊功能。 因此,列表是一個需要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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM