- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在一个简单的演示程序中定义一堆测试,其中每个测试都是本地定义的,但所有测试都可以在一个标准位置打印。
例如;
t1 = ("Sqrt(4)", sqrt(4.0))
...
t2 = ("sumList:", sum [1,2,3,4])
...
t3 = ("Description", value)
...
因此,每个测试的类型为:(字符串,值),对于各种值类型,所有这些值类型(仅)必须是 Show 类的成员。
然后是测试摘要,一个循环:
test (msg, val) = do print $ msg ++ " :: " ++ show val
tests ts = mapM test ts
这会编译并分配这些类型:
test :: Show a => ([Char], a) -> IO ()
tests :: (Traversable t, Show a) => t ([Char], a) -> IO (t ())
只有当所有测试的第二个参数都具有相同类型时,该方法才有效。我假设它以某种方式将类型专门化为实际遇到的参数类型,即使它们都是可显示的。
为了使它们可以根据第二个参数的实际类型而变化,我尝试了这样的操作(伪代码):
type ATest = (Show a) => (String, a)
由于这行不通,我尝试了:
{-# LANGUAGE RankNTypes #-}
type ATest = forall a. (Show a) => (String, a)
它可以编译,但在值参数的任何变化上仍然失败。
此外,我想从打印测试的循环中抽象出测试的类型,但我无法使用它来转换:
test :: Show a => ([Char], a) -> IO ()
to
test :: ATest -> IO ()
基本思想是在测试循环的定义中定义并使用多态类型进行测试。所以也许是一个数据结构;
data (Show a) => ATest = Test (String,a)
但这也失败了,尽管它确实给出了正确的想法;所有测试都有一个共同的结构,并在 Show 类型类中具有第二个值。
正确的方法是什么?
最佳答案
让我们首先评论一下 test
和 tests
的推断类型:
test :: Show a => ([Char], a) -> IO ()
tests :: (Traversable t, Show a) => t ([Char], a) -> IO (t ())Which works only as long as all tests have the same type for the second argument. I assume that it is somehow specializing the type to the actual encountered type of the arguments, even though they are all show'able.
这是预料之中的。列表(或任何其他可遍历的)的所有元素必须具有相同的类型。这甚至不完全是“特化”的问题:一旦类型检查器发现你试图例如用 Int
和 String
组装一个列表,它立即举起手来:
GHCi> [3 :: Int, "foo"]
<interactive>:125:12: error:
• Couldn't match expected type ‘Int’ with actual type ‘[Char]’
• In the expression: "foo"
In the expression: [3 :: Int, "foo"]
In an equation for ‘it’: it = [3 :: Int, "foo"]
一种直接的规避方法是为元素分配一个类型,该类型忽略值之间不相关的差异。这正是你试图通过引入 forall
来实现的——在你的例子中,你试图声明对的第二个元素唯一重要的是有一个显示
它们的实例:
{-# LANGUAGE RankNTypes #-}
type ATest = forall a. (Show a) => (String, a)
您提到这种方法“在值参数的任何变化上仍然失败”。我无法重现这种特定的失败模式:事实上,我什至无法说明 ATest
列表的类型:
GHCi> :set -XRankNTypes
GHCi> type ATest = forall a. (Show a) => (String, a)
GHCi> -- There is no special meaning to :{ and :}
GHCi> -- They are merely a GHCi trick for multi-line input.
GHCi> :{
GHCi| glub :: [ATest]
GHCi| glub = [("Sqrt(4)", sqrt(4.0)),("sumList:", sum [1,2,3,4])]
GHCi| :}
<interactive>:145:9: error:
• Illegal polymorphic type: ATest
GHC doesn't yet support impredicative polymorphism
• In the type signature:
glub :: [ATest]
GHC 即将拒绝:由于 ATest
只是一个类型同义词,[ATest]
扩展为 [forall a. (显示a)=>(字符串,a)]
。列表类型构造函数的参数中的 forall
需要一个称为谓语多态性的功能,该功能is not supported by GHC 。为了避免遇到这种情况,我们需要定义一个正确的数据类型,而不仅仅是一个同义词,这就是您在最后一次尝试中尝试做的事情 - 只不过您仍然需要像以前一样的 forall
:
GHCi> -- We need a different extension in this case.
GHCi> :set -XExistentialQuantification
GHCi> data ATest = forall a. Show a => ATest (String, a)
GHCi> :{
GHCi| glub :: [ATest]
GHCi| glub = [ATest ("Sqrt(4)", sqrt(4.0)),ATest ("sumList:", sum [1,2,3,4])]
GHCi| :}
GHCi>
这终于按预期工作了:
GHCi> :{
GHCi| -- I took the liberty of doing a few stylistic changes.
GHCi| test :: ATest -> IO ()
GHCi| test (ATest (msg, val)) = print $ msg ++ " :: " ++ show val
GHCi|
GHCi| tests :: Foldable t => t ATest -> IO ()
GHCi| tests = mapM_ test
GHCi| :}
GHCi> tests glub
"Sqrt(4) :: 2.0"
"sumList: :: 10"
一般而言,建议您在以这种方式使用存在量化之前寻找替代方案,因为它通常会带来比其值(value)更多的麻烦(有关此讨论的入门知识,请参阅例如问题和
How to convert my thoughts in OOP to Haskell? 中的所有答案)。然而,在这种情况下,您想要做的只是方便地指定要运行的测试列表,因此使用此策略似乎是明智的。在
Testing QuickCheck properties against multiple types? ,您可以看到一个与我们在这里使用 QuickCheck 所做的非常相似的示例,QuickCheck 是一个成熟的 Haskell 测试库。
关于haskell - 如何指定带有约束的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40371427/
我可以添加一个检查约束来确保所有值都是唯一的,但允许默认值重复吗? 最佳答案 您可以使用基于函数的索引 (FBI) 来实现此目的: create unique index idx on my_tabl
嗨,我在让我的约束在grails项目中工作时遇到了一些麻烦。我试图确保Site_ID的字段不留为空白,但仍接受空白输入。另外,我尝试设置字段显示的顺序,但即使尝试时也无法反射(reflect)在页面上
我似乎做错了,我正在尝试将一个字段修改为外键,并使用级联删除...我做错了什么? ALTER TABLE my_table ADD CONSTRAINT $4 FOREIGN KEY my_field
阅读目录 1、约束的基本概念 2、约束的案例实践 3、外键约束介绍 4、外键约束展示 5、删除
SQLite 约束 约束是在表的数据列上强制执行的规则。这些是用来限制可以插入到表中的数据类型。这确保了数据库中数据的准确性和可靠性。 约束可以是列级或表级。列级约束仅适用于列,表级约束被应用到整
我在 SerenityOS project 中偶然发现了这段代码: template void dbgln(CheckedFormatString&& fmtstr, const Parameters
我有表 tariffs,有两列:(tariff_id, reception) 我有表 users,有两列:(user_id, reception) 我的表 users_tariffs 有两列:(use
在 Derby 服务器中,如何使用模式的系统表中的信息来创建选择语句以检索每个表的约束名称? 最佳答案 相关手册是Derby Reference Manual .有许多可用版本:10.13 是 201
我正在使用 z3py 进行编码。请参阅以下示例。 from z3 import * x = Int('x') y = Int('y') s = Solver() s.add(x+y>3) if s.c
非常快速和简单的问题。我正在运行一个脚本来导入数据并声明了一个临时表并将检查约束应用于该表。显然,如果脚本运行不止一次,我会检查临时表是否已经存在,如果存在,我会删除并重新创建临时表。这也会删除并重新
我有一个浮点变量 x在一个线性程序中,它应该是 0或两个常量之间 CONSTANT_A和 CONSTANT_B : LP.addConstraint(x == 0 OR CONSTANT_A <= x
我在使用grails的spring-data-neo4j获得唯一约束时遇到了一些麻烦。 我怀疑这是因为我没有正确连接它,但是存储库正在扫描和连接,并且CRUD正在工作,所以我不确定我做错了什么。 我正
这个问题在这里已经有了答案: Is there a constraint that restricts my generic method to numeric types? (24 个回答) 7年前
我有一个浮点变量 x在一个线性程序中,它应该是 0或两个常量之间 CONSTANT_A和 CONSTANT_B : LP.addConstraint(x == 0 OR CONSTANT_A <= x
在iOS的 ScrollView 中将图像和带有动态文本(动态高度)的标签居中的最佳方法是什么? 我必须添加哪些约束?我真的无法弄清楚它是如何工作的,也许我无法处理它,因为我是一名 Android 开
考虑以下代码: class Foo f class Bar b newtype D d = D call :: Proxy c -> (forall a . c a => a -> Bool) ->
我有一个类型类,它强加了 KnownNat约束: class KnownNat (Card a) => HasFin a where type Card a :: Nat ... 而且,我有几
我知道REST原则上与HTTP无关。 HTTP是协议,REST是用于通过Web传输hypermedia的体系结构样式。 REST可以使用诸如HTTP,FTP等的任何应用程序层协议。关于REST的讨论很
我有这样的情况,我必须在数据库中存储复杂的数据编号。类似于 21/2011,其中 21 是文件编号,但 2011 是文件年份。所以我需要一些约束来处理唯一性,因为有编号为 21/2010 和 21/2
我有一个 MySql (InnoDb) 表,表示对许多类型的对象之一所做的评论。因为我正在使用 Concrete Table Inheritance ,对于下面显示的每种类型的对象(商店、类别、项目)
我是一名优秀的程序员,十分优秀!