- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在和 Idris 一起玩,我遇到了一些让我有点困惑的事情:
以下类型检查:
conc : Vect n a -> Vect m a -> Vect (n+m) a
conc [] ys = ys
conc (x :: xs) ys = x :: (conc xs ys)
但这不是:
conc : Vect n a -> Vect m a -> Vect (m+n) a
conc [] ys = ys
conc (x :: xs) ys = x :: (conc xs ys)
出现以下错误:
When checking right hand side of conc with expected type
Vect (m + 0) a
Type mismatch between
Vect m a (Type of ys)
and
Vect (plus m 0) a (Expected type)
Specifically:
Type mismatch between
m
and
plus m 0
相当于 xs++ys 类型检查,但 ys++xs 不匹配,即使它们都匹配长度为 n+m 的类型定义。
这让我有点吃惊,因为加法是可交换的。我可以对函数签名做些什么(可能有约束?)以同时检查 xs++ys 和 ys++xs 表达式类型检查?
最佳答案
对于Idris 的初学者来说,这是一个常见的困惑话题。第二个 conc
版本中这种情况下的问题:
conc : Vect n a -> Vect m a -> Vect (m+n) a
conc [] ys = ys
Idris 不能应用加法交换性,因为从编译器的角度来看,Nat plus 交换性 是一个定理。这里是它的类型:
Idris> :t plusCommutative
plusCommutative : (left : Nat) -> (right : Nat) -> left + right = right + left
没有一般规则可以告诉您选择和应用哪个定理。当然,可以针对一些简单的情况进行一些启发式,例如 Nat 可交换性。但这也可能使其他一些情况难以理解。
你需要考虑的另一件事是plus
的定义:
Idris> :printdef plus
plus : Nat -> Nat -> Nat
plus 0 right = right
plus (S left) right = S (plus left right)
函数 plus
以这样的方式定义,即对其第一个参数进行模式匹配。 Idris 实际上可以在类型中执行这种模式匹配。所以在第一个版本中,在哪里
conc : Vect n a -> Vect m a -> Vect (n+m) a
conc [] ys = ys
你有 (0 + m) 类型并且 Idris 可以用 m
替换 plus 0 m
并且所有的类型检查。如果您通过对第二个参数进行模式匹配来定义 +
运算符,则 plus m 0
将起作用。例如,这样编译:
infixl 4 +.
(+.) : Nat -> Nat -> Nat
n +. Z = n
n +. (S m) = S (n +. m)
conc : Vect n a -> Vect m a -> Vect (m +. n) a
conc [] ys = ys
conc (x :: xs) ys = x :: (conc xs ys)
但很明显,为您需要的每种情况编写新的运算符是可怕的。因此,为了使您的第二个版本可编译,您应该在 Idris 中使用 rewrite ... in
语法。你需要下一个定理:
Idris> :t plusZeroRightNeutral
plusZeroRightNeutral : (left : Nat) -> left + 0 = left
Idris> :t plusSuccRightSucc
plusSuccRightSucc : (left : Nat) -> (right : Nat) -> S (left + right) = left + S right
Idris> :t sym
sym : (left = right) -> right = left
这是编译的版本:
conc : Vect n a -> Vect m a -> Vect (m + n) a
conc {m} [] ys = rewrite plusZeroRightNeutral m in ys
conc {n=S k} {m} (x :: xs) ys = rewrite (sym $ plusSuccRightSucc m k) in x :: (conc xs ys)
我不是在这里解释 rewriting
和定理证明是如何工作的。如果您不了解某些内容,这是另一个问题的主题。但是您可以在教程中阅读相关内容(或等待本书发布 :)。
关于idris - 两个向量的串联 - 为什么长度不被视为可交换的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42534191/
我正在学习 Idris 并且我陷入了一个非常简单的引理,该引理表明某些特定索引对于数据类型是不可能的。我尝试使用不可能的模式,但 Idris 拒绝使用以下错误消息: RegExp.idr line 3
灵感来自 this blog post和 this code我想我会使用 Idris 的接口(interface)(类型类)在 Idris 中尝试一些类别理论。 我定义了Category如下,效果很好
借此我可以构建一个匿名的临时记录;那是可编辑的、可附加的、可修改的,其中每个值可以具有不同的异构类型,以及编译器检查消费者类型期望是否与所有给定键处生成的记录的类型一致? 类似于 Purescript
是否有一种简单的方法可以为数据类型编写相等 ( DecEq ) 实例?例如,我希望下面的 DecEq 中有 O(n) 行声明,其中 ?p很简单: data Foo = A | B | C | D in
是否有任何关于 postulate 的性质和用途的最新信息?在 idris build ?教程/手册中没有关于该主题的任何内容,我似乎也无法在 wiki 中找到任何内容。 TIA。 最佳答案 我认为我
在玩了一下 Idris 及其效果教程示例后,我终于弄清楚了如何链接效果。不确定链是否是正确的词,但我基本上是指一种效果是根据另一种效果实现的。 在这个例子中,我有一个效果,我称之为 Lower。它直接
Idris 中是否存在有理数的现有实现? 例如Data.Ratio 来自 Haskell 的端口。 最佳答案 通过快速搜索,我找到了 this , 如果它可能很有趣 关于idris - Idris 中
在官方 Idris wiki 上的非官方常见问题解答(官方是因为它在该语言的 git 仓库中),它是 stated that in a total language [e.g. Idris] we d
我在看 Idris tutorial .我无法理解以下代码。 disjoint : (n : Nat) -> Z = S n -> Void disjoint n p = replace {P = d
在 Idris 中定义我们在其他语言中称为常量的惯用方式是什么?是这个吗? myConstant : String myConstant = "some_constant1" myConstant2
在 idris 0.9.17.1 中, 灵感来自 https://wiki.haskell.org/Prime_numbers , 我编写了以下代码来生成素数 module Main concat:
我编写了一个函数doSomething,它接受一个左括号或右括号并返回相应的Int: doSomething : (c : Char) -> {auto isPar : c == '(' || c =
这实际上是我的第一行 Idris 代码。当我查阅文档时,一切都显得正确: Idris> data T = Foo Bool | Bar (T -> T) (input):1:6: | 1 | da
我正在使用 Idris 进行类型驱动开发,学习如何定义具有可变数量参数的函数。我有点野心,想写一个 mapN将映射 (n : Nat) 的函数的函数参数到 n一些 Applicative 的值类型。
我正在尝试编写一个函数 mSmallest需要两个自然数,n和 m作为输入并产生一个向量。输出向量包含 m有限集的最小成员 n成员。 例如 mSmallest 5 3应该生产 [FS (FS Z),
我在 Idris 中将幺半群定义为 interface Is_monoid (ty : Type) (op : ty -> ty -> ty) where id_elem : () -> ty
我正在阅读 Type driven development with Idris ,其中一个练习要求读者定义一个类型 TupleVect ,这样一个向量可以表示为: TupleVect 2 ty =
试图证明以下断言: equalityCommutesNat : (n : Nat) -> (m : Nat) -> n = m -> m = n 我找到了 plusCommutes在图书馆里,但没有平
为什么 Idris 要求函数按照定义的顺序出现,并使用 mutual 声明的相互递归? 我希望 Idris 执行函数之间的第一次依赖分析,并自动对它们进行重新排序。我一直相信 Haskell 是这样做
我一直无法让 Idris 整体检查器相信我的功能是完整的。这是我遇到的问题的一个简单示例版本。假设我们有一个如下形式的非常简单的表达式类型: data SimpleType = Prop | Fn S
我是一名优秀的程序员,十分优秀!