基于输入类型的延续函数实现?
Continuation function implementations based upon input type?
我有一个非常简单的延续函数(为简单起见避免使用 Monad):
data C a = C {unwrap :: (a -> a) -> a}
本质上,我试图根据输入类型执行不同的实现,类似于 (sudo-code):
data Gadt a where
AString :: String -> Gadt Bool
AInt :: Int -> Gadt Bool
data C a = C {unwrap :: (a -> Gadt a) -> a}
example :: a -> C a
example v = C $ \f -> | (v :: Int) == True = f (AInt v)
| (v :: String) == True = f (AString v)
cont :: Gadt a -> a
cont (AInt v) = ...
cont (AString v) = ...
我是否忽略了这里的基本解决方案?我是 continuation 的新手,所以我可能只是忽略了一些简单的事情。
首先你不能使用::
作为测试运行时类型的谓词(据我所知)。其次,Gadt
的 a
参数完全是幻影。这是故意的吗? example
可以通过统一处理不同类型来实现多态,或者您需要使用 class
(parametric vs ad-hoc 多态)。你可能想要像
这样的东西
data Gadt where
AInt :: Int -> Gadt
AString :: String -> Gadt
data C a = C { unwrap :: (a -> Gadt) -> Gadt }
class Ex a where
example :: a -> C a
instance Ex Int where
example v = C ...
instance Ex String where
example v = C ...
这仍然是伪代码,因为它没有什么意义,但至少对我来说是类型检查。
根据 here 的建议,我找到了一个可能的解决方案:
newtype C r a = C {runC :: (a -> r) -> r}
data Hole = Hole1 Int | Hole2 String | Hole3 Bool
example :: String -> C Bool a
example s = C $ \f -> do
x <- f (Hole1 22)
y <- f (Hole2 "string")
k (Hole3 False)
cont :: Hole -> Bool
cont (Hole1 x) = ...
cont (Hole2 x) = ...
cont (Hole3 x) = ...
这通过将输入类型包装在 Hole
数据结构中来启用基于类型的特定实现。
我有一个非常简单的延续函数(为简单起见避免使用 Monad):
data C a = C {unwrap :: (a -> a) -> a}
本质上,我试图根据输入类型执行不同的实现,类似于 (sudo-code):
data Gadt a where
AString :: String -> Gadt Bool
AInt :: Int -> Gadt Bool
data C a = C {unwrap :: (a -> Gadt a) -> a}
example :: a -> C a
example v = C $ \f -> | (v :: Int) == True = f (AInt v)
| (v :: String) == True = f (AString v)
cont :: Gadt a -> a
cont (AInt v) = ...
cont (AString v) = ...
我是否忽略了这里的基本解决方案?我是 continuation 的新手,所以我可能只是忽略了一些简单的事情。
首先你不能使用::
作为测试运行时类型的谓词(据我所知)。其次,Gadt
的 a
参数完全是幻影。这是故意的吗? example
可以通过统一处理不同类型来实现多态,或者您需要使用 class
(parametric vs ad-hoc 多态)。你可能想要像
data Gadt where
AInt :: Int -> Gadt
AString :: String -> Gadt
data C a = C { unwrap :: (a -> Gadt) -> Gadt }
class Ex a where
example :: a -> C a
instance Ex Int where
example v = C ...
instance Ex String where
example v = C ...
这仍然是伪代码,因为它没有什么意义,但至少对我来说是类型检查。
根据 here 的建议,我找到了一个可能的解决方案:
newtype C r a = C {runC :: (a -> r) -> r}
data Hole = Hole1 Int | Hole2 String | Hole3 Bool
example :: String -> C Bool a
example s = C $ \f -> do
x <- f (Hole1 22)
y <- f (Hole2 "string")
k (Hole3 False)
cont :: Hole -> Bool
cont (Hole1 x) = ...
cont (Hole2 x) = ...
cont (Hole3 x) = ...
这通过将输入类型包装在 Hole
数据结构中来启用基于类型的特定实现。