因此,在练习中,我获得了诸如["xyz", True, 42]
之类的列表。问题是这是否是Haskell中的有效表达方式,该表达式的类型是什么。
列表只能容纳同质类型,但是"xyz"
的类型为[Char]
,True
的类型为Bool
,42
的类型为Num p => p
。那是不同的类型,所以我不能将它们列入列表。
这就是我的想法。但是对该练习的给定答案是"是的,这是一个有效的表达。示例!。"
尽管列表元素的类型是不同的?我正在考虑类似于面向对象的语言的超类,但我认为这不是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
pragma编写它:
{-# LANGUAGE OverloadedStrings #-}
the_list = ["xyz", True, 42]
这将等效于:
Prelude Data.String> ["xyz", True, 42]
[True,True,True]
但请注意,该列表仍然只包含Bool
s,我们仅使Bool
成为IsString
和Num
的实例,使我们能够将字符串 literals 和number lintals 转换为 Bool
s。
Haskell中无法使用异质类型的列表,并且由于默认情况下,Bool
不是Num
,因此我们无法在不添加一些额外的魔法的情况下解析该表达式。
另外一个说明是它是有效的haskell grammar :语法上没有错,只有在编译器的下一阶段:类型检查等。语法是毫无意义的。
我的讲师给了我一个提示,以检查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
这起作用并确实产生了练习的输入。必须在第一行中存在的存在量化的数据类型扩展。
我的解释(尽管我可能遇到了问题(:
i使用一个构造函数
MkShowable
创建一个新类型的Showable
,只要在TypeClassShow
中使用任何值a
,就可以将Showable
从中添加出来。方法包使
Show a
通过使用1。
中描述的构造函数Showable
是Show
-Typeclass的实例,并告诉Showable
(MkShowable a
(,只需显示a
即可。因此我们可以轻松打印Showable
s。
MkShowable
成为Showable
此外,我创建了一个类型[Showable]
的(异源(列表hlist
,并使用pack
从我的示例中填充了值。该列表打印在主要功能中。
这确实使我想起了面向对象的编程。