[英]Explanation why a list with different types is a valid Haskell expression needed
因此,在练习中,我会得到一个像["xyz", True, 42]
这样的列表。 问题是,这是否是Haskell中的有效表达式以及该表达式的类型。
列表只能包含同类型,但"xyz"
的类型是[Char]
, True
的类型是Bool
, 42
的类型是Num p => p
。 这是不同的类型,所以我不能把它们列入一个列表。
那正是我所想。 但是这个练习的答案是“是的,它是一个有效的表达式。显示实例!”。
为什么它是一个有效的表达式,尽管列表元素的类型不同,show-instance是什么意思? 我正在考虑类似于面向对象语言的超类,但我认为这不是Haskell的工作方式。
如果允许我们定义更多的上下文,我们可以使它成为一个有效的表达式,例如:
import Data.String(IsString(fromString))
instance IsString Bool where
fromString [] = False
fromString _ = True
instance Num Bool where
(+) = (||)
(*) = (&&)
abs = id
signum = id
fromInteger 0 = False
fromInteger _ = True
negate = not
(这里我使用Python的真实性从Integer
和String
文字转换)
然后我们可以使用OverloadedStrings
编译指示编写它:
{-# LANGUAGE OverloadedStrings #-}
the_list = ["xyz", True, 42]
这相当于:
Prelude Data.String> ["xyz", True, 42]
[True,True,True]
但请注意,该列表仍然只包含Bool
,我们只使Bool
成为IsString
和Num
的实例,使我们能够将字符串文字和数字文字转换为Bool
。
Haskell中不可能列出异构类型,并且由于默认情况下Bool
不是Num
,因此我们无法在不添加额外魔法的情况下解析该表达式。
另一个注意事项是它是有效的Haskell 语法 :语法上没有任何错误,它只在编译器的下一个阶段:类型检查等,它会引发错误,因为语法是荒谬的 。
我的讲师给了我一个提示,检查Haskell中的存在类型 。
我从上面链接的描述中产生了一个工作示例:
{-# LANGUAGE ExistentialQuantification #-}
module Main where
data Showable = forall a . Show a => MkShowable a
pack:: Show a => a -> Showable
pack a= MkShowable a
instance Show Showable where
show (MkShowable a) = show a
hlist :: [Showable]
hlist = [pack "xyz", pack True, pack 42]
main :: IO ()
main = do
putStrLn "Heterogenous list 'camouflaged' as Showable:"
print hlist
这有效并且确实产生了练习的输入。 第一行中存在量化的数据类型扩展是必要的。
我的解释(虽然我可能遇到了错误):
我创建了一个新的类型Showable
一个构造函数MkShowable
可以接收任意值a
,只要它是在类型类Show
,从而使得Showable
出来。
方法包通过使用我在1中描述的构造函数MkShowable
使Show a
成为Showable
。
Showable
是Show
-typeclass的一个实例,并告诉我如果要显示一个Showable
( MkShowable a
),只需显示a
。 所以我们可以轻松打印我们的Showable
。
此外,我创建了一个[Showable]
列表hlist
,类型为[Showable]
并使用pack
我的示例中的值打包到其中。 列表打印在主函数中。
这真的让我想起了面向对象的编程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.