Sil*_*olo 6 haskell types existential-type
在Haskell的existentials上阅读本页后,我不得不测试这种行为的限制,所以我编写了以下代码片段:
{-# LANGUAGE ExistentialQuantification #-}
data Showable = forall a. Show a => MkShowable a
pack :: Show a => a -> Showable
pack = MkShowable
instance Show Showable where
show (MkShowable x) = show x
Run Code Online (Sandbox Code Playgroud)
该Showable类型ShowBox与上述链接中创建的类型非常相似.然后我创建了这个人为的例子来说明我的问题.
showSomething :: Bool -> Showable
showSomething True = pack 1
showSomething False = pack "ABC"
main :: IO ()
main = do
x <- getLine
let y = read x
print $ showSomething y
Run Code Online (Sandbox Code Playgroud)
这段代码(工作正常)要求用户输入(应为'True'或'False'),然后打印输出1是否为True或"ABC"是否为False.
但我没能完全理解系统是如何做到这一点的.从数学上讲,它非常有意义.但我不知道计算机是如何解决它的.对我来说,它看起来像系统使得在关于是否调用运行时决定Int的show实例或String的show功能,但是这将意味着一个像C++的虚函数表,我不相信Haskell有一个概念存在.
我的问题是:它如何解决这个问题?系统无法预先知道我是要输入true还是false,因此它无法知道show在编译时调用哪个,但它在两种情况下都清楚有效.
实现类型类的一种方法是传递一个实现类型类的函数字典.例如带签名的函数
f :: Show a => T
Run Code Online (Sandbox Code Playgroud)
将被翻译成
f' :: (a -> String) -> T
Run Code Online (Sandbox Code Playgroud)
由编译器和show内部使用的时候f,它被附加参数替换(实际上会有更多的函数,所有声明的函数Show).
同样是数据类型
forall a . Show a => MkShowable a
Run Code Online (Sandbox Code Playgroud)
将被翻译成
forall a . MkShowable' (a -> String) a
Run Code Online (Sandbox Code Playgroud)
所以转换后的代码可能如下所示:
{-# LANGUAGE ExistentialQuantification #-}
data Showable' = forall a . MkShowable' (a -> String) a
pack' :: Show a => a -> Showable'
pack' = MkShowable' show
instance Show Showable' where
show (MkShowable' f x) = f x
showSomething :: Bool -> Showable'
showSomething True = pack' 1
showSomething False = pack' "ABC"
Run Code Online (Sandbox Code Playgroud)
当pack被调用时,show实现传递给构造以及以便在需要时,它的可用.
| 归档时间: |
|
| 查看次数: |
136 次 |
| 最近记录: |