说明为什么具有不同类型的列表是需要有效的Haskell表达式



因此,在练习中,我获得了诸如["xyz", True, 42]之类的列表。问题是这是否是Haskell中的有效表达方式,该表达式的类型是什么。

列表只能容纳同质类型,但是"xyz"的类型为[Char]True的类型为Bool42的类型为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的真实性来转换为IntegerString字面(

然后我们可以用OverloadedStrings pragma编写它:

{-# LANGUAGE OverloadedStrings #-}
the_list = ["xyz", True, 42]

这将等效于:

Prelude Data.String> ["xyz", True, 42]
[True,True,True]

但请注意,该列表仍然只包含Bool s,我们仅使Bool成为IsStringNum的实例,使我们能够将字符串 literals 和number lintals 转换为 Bools。

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

这起作用并确实产生了练习的输入。必须在第一行中存在的存在量化的数据类型扩展。

我的解释(尽管我可能遇到了问题(:

  1. i使用一个构造函数MkShowable创建一个新类型的Showable,只要在TypeClass Show中使用任何值a,就可以将Showable从中添加出来。

  2. 方法包使Show a通过使用1。

  3. 中描述的构造函数MkShowable成为Showable
  4. ShowableShow -Typeclass的实例,并告诉Showable(MkShowable a(,只需显示a即可。因此我们可以轻松打印Showables。

此外,我创建了一个类型[Showable]的(异源(列表hlist,并使用pack从我的示例中填充了值。该列表打印在主要功能中。

这确实使我想起了面向对象的编程。

最新更新