Tôi muốn nâng một hàm Haskell vào trong mã hóa tính toán lambda bậc cao hơn. Điều này được thực hiện gần như nguyên văn từ mã hóa Taged cuối cùng của Oleg.Thủ thuật Typeclass cho chức năng đa thông số tổng quát nâng
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
Tôi có thể nhúng các loại Haskell tùy ý vào Lam
sử dụng emb
, nhưng tôi không thể sử dụng (^)
cho các ứng dụng sau đó. Hơn nữa, các chức năng nâng sẽ hoạt động uể oải. Thay vào đó, tôi phải nâng ứng dụng đó lên bằng ứng dụng.
emb1 :: (Applicative r, Lam r)
=> (a -> b) -> r (r a -> r b)
emb1 f = lam $ \ra -> f <$> ra
emb2 :: (Applicative r, Lam r)
=> (a -> b -> c) -> r (r a -> r (r b -> r c))
emb2 f = lam $ \ra -> lam $ \rb -> f <$> ra <*> rb
emb3 :: (Applicative r, Lam r)
=> (a -> b -> c -> d)
-> r (r a -> r (r b -> r (r c -> r d)))
emb3 f = lam $ \ra -> lam $ \rb -> lam $ \rc -> f <$> ra <*> rb <*> rc
>>> eval $ emb2 (+)^emb 1^emb 2
3
Đó là rất nhiều lò hơi. Tôi muốn tạo ra một chức năng nâng chung mà sẽ làm việc cho bất kỳ chức năng tinh thần. Tôi cảm thấy như nó có thể sử dụng một cái gì đó giống như của Printf
's PrintfType
hoặc fixed-vector
' s Cont
loại. Tôi có thể chỉ định những gì tôi muốn sử dụng chức năng loại
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 = ?
Nhưng tôi rất khó khăn thông qua phương pháp này, thường do các vấn đề về tiêm. Tôi đã có thể giải quyết tiêm với một sự kết hợp thực sự ghê tởm của wrapper newtype và biến kiểu scoped, nhưng nó không bao giờ thực sự gõ kiểm tra.
Điều này có thể diễn tả trong Haskell không?
Tôi không biết câu trả lời, nhưng liên kết tiếp theo có thể hữu ích: http://hackage.haskell.org/package/layers-0.1/docs/Documentation-Layers-Overview.html – wit