- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我很难说服编译器我的类型是正确的。定期
具有Nat
和Zero
构造函数的Succ
很简单(目标是为长度索引列表(replicate
)编写Vect
函数):
replicate' :: SNat n -> a -> Vect n a
replicate' SZero _ = Nil
replicate' (SSucc n) a = a :> replicate' n a
Nat
非常慢。
sameNat :: forall a b. (KnownNat a, KnownNat b) => SNat a -> SNat b -> Maybe (a :~: b)
sameNat x y
| natVal (Proxy :: Proxy a) == natVal (Proxy :: Proxy b) = Just (unsafeCoerce Refl)
| otherwise = Nothing
replicate'' :: (KnownNat n) => SNat n -> a -> Vect n a
replicate'' n a =
case sameNat n (sing :: Sing 0) of
Just Refl -> Nil
Nothing -> a ::> replicate'' (sPred n) a
Couldn't match type ‘n’
with ‘(n GHC.TypeNats.- 1) GHC.TypeNats.+ 1’
最佳答案
问题是,在n为零的情况下(当在sameNat n (sing :: Sing 0)
上进行模式匹配时),n ~ 0
为您提供了可用的Just Refl
证明,但是如果n不为零,则仅为您提供Nothing
。这完全没有告诉您有关n
的任何信息,因此就类型检查器而言,您可以在Nothing
分支内完全调用相同的东西集,而无需首先调用sameNat
(特别是,您不能使用sPred
,因为这需要该1 <= n
)。
因此,我们需要对提供n ~ 0
证据或1 <= n
证据的事物进行模式匹配。像这样:
data IsZero (n :: Nat)
where Zero :: (0 ~ n) => IsZero n
NonZero :: (1 <= n) => IsZero n
deriving instance Show (IsZero n)
replicate''
:
isZero :: forall n. SNat n -> IsZero n
isZero n = _
replicate'' :: SNat n -> a -> Vect n a
replicate'' n x = case isZero n
of Zero -> Nil
NonZero -> x ::> replicate'' (sPred n) x
isZero
函数上,该函数实际上并没有给我们买任何东西,但是我会坚持使用它,因为将其作为您想要的任何其他归纳定义的基础很方便使用
Nat
进行。
isZero
。我们当然可以用
sameNat
处理零大小写,但这无助于非零大小写。单例包还提供了
Data.Singletons.Decide
,它为您提供了一种基于单例来证明类型相等或不相等的方法。因此,我们可以这样做:
isZero :: forall n. SNat n -> IsZero n
isZero n = case n %~ (SNat @0)
of Proved Refl -> Zero
Disproved nonsense -> NonZero
Proved
的情况很好(基本上与
sameNat
赋予我们
Just Refl
相同)。但是“不等式的证明”以
nonsense
绑定到类型为
(n :~: 0) -> Void
的函数的形式出现,并且如果我们假设全部(没有假名),则该函数的存在“证明”我们不能构造一个
n :~: 0
值,该值证明
n
绝对不是
0
。但这与
1 <= n
的证明相距太远。我们可以看到,如果
n
不为0,那么从自然数的属性来看,它必须至少为1,但是GHC不知道这一点。
Ord
上使用单例的
SNat @1 :%<= n
支持和模式匹配:
isZero :: forall n. SNat n -> IsZero n
isZero n = case (SNat @1) %:<= n
of STrue -> NonZero
SFalse -> Zero
STrue
和
SFalse
只是类型级别
True
和
False
的单例,与原始比较断开了连接。我们从任一方面都没有得到
0 ~ n
或
1 <= n
的证据(同样,通过与
SNat @0
进行比较,也无法使其起作用)。基本上,这是类型检查器布尔盲。
<
或
<=
约束的方式比较单身人士,要么需要切换
Nat
为零还是非零。
isZero :: forall n. SNat n -> IsZero n
isZero n = case n %~ (SNat @0)
of Proved Refl -> Zero
Disproved _ -> unsafeCoerce (NonZero @1)
NonZero
仅包含
n
为1或更大的证据,而没有包含有关
n
的任何其他信息,因此您可以不安全地强制使用1为1或更大的证据。
{-# LANGUAGE DataKinds
, GADTs
, KindSignatures
, ScopedTypeVariables
, StandaloneDeriving
, TypeApplications
, TypeOperators
#-}
import GHC.TypeLits ( type (<=), type (-) )
import Data.Singletons.TypeLits ( Sing (SNat), SNat, Nat )
import Data.Singletons.Prelude.Enum ( sPred )
import Data.Singletons.Decide ( SDecide ((%~))
, Decision (Proved, Disproved)
, (:~:) (Refl)
)
import Unsafe.Coerce ( unsafeCoerce )
data IsZero (n :: Nat)
where Zero :: (0 ~ n) => IsZero n
NonZero :: (1 <= n) => IsZero n
deriving instance Show (IsZero n)
isZero :: forall n. SNat n -> IsZero n
isZero n = case n %~ (SNat @0)
of Proved Refl -> Zero
Disproved _ -> unsafeCoerce (NonZero @1)
data Vect (n :: Nat) a
where Nil :: Vect 0 a
(::>) :: a -> Vect (n - 1) a -> Vect n a
deriving instance Show a => Show (Vect n a)
replicate'' :: SNat n -> a -> Vect n a
replicate'' n x = case isZero n
of Zero -> Nil
NonZero -> x ::> replicate'' (sPred n) x
head'' :: (1 <= n) => Vect n a -> a
head'' (x ::> _) = x
main :: IO ()
main = putStrLn
. (:[])
. head''
$ replicate''
(SNat @1000000000000000000000000000000000000000000000000000000)
'\x1f60e'
unsafeCoerce
的方法不同,此处的复制代码实际上是使用类型检查器来验证其是否根据提供的
Vect n a
构造了
SNat n
,而他们的建议则要求您信任代码执行此操作(实际工作的实质是通过
iterate
依靠
Int
来完成),并且仅确保调用者一致地使用
SNat n
和
Vect n a
。您只需信任的唯一代码(未经编译器检查)是
Refuted _ :: Decision (n :~: 0)
确实在
1 <= n
内暗示了
isZero
(您可以重复使用它们来编写许多其他功能,这些功能需要打开或关闭)
SNat
是否为零)。
Vect
实现更多功能时,您会发现GHC对
Nat
属性不了解的许多“显而易见的”东西是很痛苦的。
Data.Constraint.Nat
包中的
constraints
有很多有用的证明可供您使用(例如,如果您尝试实现
drop :: (k <= n) => SNat k -> Vect n a -> Vect (n - k) a
,则可能最终需要
leTrans
,这样当您知道
1 <= k
然后也可以
1 <= n
进行模式匹配以剥离另一个元素)。 K. A. Buhr的方法可以避免此类杂乱无章,这对您很有帮助,如果您只想使用您信任的代码来实现您的操作,并且不安全地强制要排队的类型。
关于haskell - Haskell单例:排版包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46634706/
单向链表 单向链表比顺序结构的线性表最大的好处就是不用保证存放的位置,它只需要用指针去指向下一个元素就能搞定。 单链表图解 图画的比较粗糙,简单的讲解一下: 上面四个长方形,每个长方
使用TCP,我正在设计一些类似于next的程序。 客户端在许多线程中的接收正在等待一台服务器的发送消息。但是,这是有条件的。 recv正在等待特定的发送消息。 例如 客户 thread 1: recv
我正在编写正则表达式来验证电子邮件。唯一让我困惑的是: 顶级域名可以使用单个字符吗?(例如:lockevn.c) 背景:我知道顶级域名可以是 2 个字符到任意字符(.uk、.us 到 .canon、.
是否可以在单个定义中定义同一 Controller 的多个路由? 例如: 我想要一个单一的定义 /, /about, /privacy-policy 使用类似的东西 _home: pat
我正在使用 objective-c开发针对 11.4 iOS 的单 View 应用程序,以及 Xcode版本是 9.4.1。 创建后有Main.storyboard和LaunchScreen.stor
我一直在尝试在 shell 程序中实现管道结构,如果我执行简单的命令(例如“hello | rev”),它就可以工作 但是当我尝试执行“head -c 1000000/dev/urandom | wc
此表包含主机和接口(interface)列UNIQUE 组合* 编辑:这个表也有一个自动递增的唯一 ID,抱歉我应该在之前提到这个 ** | host.... | interface..... |
我想将具有固定补丁大小的“std filter”应用于单 channel 图像。 也就是说,我希望 out[i,j] 等于 img[i,j] 附近的像素值的标准值。 对于那些熟悉 Matlab 的人,
假设我想进行网络调用并使用 rx.Single,因为我希望只有一个值。 我如何应用replay().autoConnect() 这样的东西,这样当我从多个来源订阅时网络调用就不会发生多次?我应该使用
我将图像从 rgb 转换为 YUV。现在我想单独找到亮度 channel 的平均值。你能告诉我如何实现这一目标吗?此外,有没有办法确定图像由多少个 channel 组成? 最佳答案 你可以这样做: #
在比较Go和Scala的语句结束检测时,我发现Scala的规则更丰富,即: A line ending is treated as a semicolon unless one of the foll
在IEEE 1800-2005或更高版本中,&和&&二进制运算符有什么区别?它们相等吗? 我注意到,当a和b的类型为bit时,这些coverpoint定义的行为相同: cp: coverpoint a
我正在使用Flutter的provider软件包。我要实现的是为一个 View 或页面提供一个简单的提供程序。因此,我在小部件中尝试了以下操作: Widget build(BuildContext c
我正在尝试在 cython 中使用 openmp。我需要在 cython 中做两件事: i) 在我的 cython 代码中使用 #pragma omp single{} 作用域。 ii) 使用#pra
我正在尝试从转义字符字符串中删除单引号和双引号。它对单引号 ' 或双自动 " 不起作用。 请问有人可以帮忙吗? var mysting = escapedStr.replace(/^%22/g, '
我正在尝试在 cython 中使用 openmp。我需要在 cython 中做两件事: i) 在我的 cython 代码中使用 #pragma omp single{} 作用域。 ii) 使用#pra
我正在使用 ANT+ 协议(protocol),将智能手机与 ANT+ USB 加密狗连接,该加密狗通过 SimulANT+ 连接到 PC。 SimulANT+ 正在模拟一个心率传感器,它将数据发送到
有人可以解释/理解单/多线程模式下计算结果的不同吗? 这是一个大约的例子。圆周率的计算: #include #include #include const int itera(100000000
我编写了一个粗略的阴影映射实现,它使用 6 个不同的 View 矩阵渲染场景 6 次以创建立方体贴图。 作为优化,我正在尝试使用几何着色器升级到单 channel 方法,但很难从我的着色器获得任何输出
尝试使用 Single-Spa 构建一些东西并面临添加到应用程序 AngularJS 的问题。 Angular2 和 ReactJs 工作完美,但如果添加 AngularJS 并尝试为此应用程序使用
我是一名优秀的程序员,十分优秀!