haskell - Haskell 中存在量化值的列表

标签 haskell types type-systems higher-rank-types

我想知道为什么这段代码不进行类型检查:

{-# LANGUAGE ScopedTypeVariables, Rank2Types, RankNTypes #-}
{-# OPTIONS -fglasgow-exts #-}

module Main where

foo :: [forall a. a]
foo = [1]

ghc 提示:
Could not deduce (Num a) from the context ()
  arising from the literal `1' at exist5.hs:7:7

鉴于:
Prelude> :t 1
1 :: (Num t) => t
Prelude> 

似乎 (Num t) 上下文无法匹配 arg 的 () 上下文。我无法理解的一点是,由于 () 比 (Num t) 更通用,因此后者应该包含前者。这与缺乏 Haskell 对子类型的支持有关吗?

感谢您对此发表任何评论。

最佳答案

你在这里没有使用存在量化。您正在使用等级 N 类型。

这里[forall a. a]意味着每个元素必须具有所有可能的类型(不是任何,每个)。所以[undefined, undefined]将是该类型的有效列表,基本上就是这样。

稍微扩展一下:如果列表的类型为 [forall a. a]这意味着所有元素的类型都是 forall a. a .这意味着任何接受任何类型参数的函数都可以将该列表的一个元素作为参数。如果你放入一个比 forall a. a 更具体的类型的元素,这将不再正确。 ,所以你不能。

要获得可以包含任何类型的列表,您需要使用存在量化定义自己的列表类型。像这样:

data MyList = Nil | forall a. Cons a MyList
foo :: MyList
foo = Cons 1 Nil

当然,除非您限制元素类型至少实例化 Show ,你不能对那种类型的列表做任何事情。

关于haskell - Haskell 中存在量化值的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3149975/

相关文章:

haskell - 将 ByteString 转换为 Int 的最佳方法是什么?

haskell - 在 Haskell 中的函数列表上折叠

mysql - MySQL 5.0 中的 int 和 integer 有什么区别?

Python:如何检查对象的属性是否是方法?

scala - 如何避免 Scala 中类型绑定(bind)的重复

haskell - 从具有函数作为 Haskell 中的字段的数据类型派生 Eq 时出现问题

haskell - 为什么类型实例 (a->a) 和 (a->a->a) 在 GHC 7.8 中发生冲突?

java - 确保输入参数满足多个类型标准

dynamic-typing - Matlab:为什么是 '1' + 1 == 50?

haskell - 我如何解释这篇论文上的打字规则?