gpt4 book ai didi

haskell - 实时持久队列总数

转载 作者:行者123 更新时间:2023-12-03 20:51:11 24 4
gpt4 key购买 nike

Okasaki 描述了可以在 Haskell 中使用类型实现的持久实时队列

data Queue a = forall x . Queue
{ front :: [a]
, rear :: [a]
, schedule :: [x]
}

其中增量旋转保持不变
length schedule = length front - length rear

更多细节

如果您熟悉所涉及的队列,则可以跳过本节。

旋转功能看起来像
rotate :: [a] -> [a] -> [a] -> [a]
rotate [] (y : _) a = y : a
rotate (x : xs) (y : ys) a =
x : rotate xs ys (y : a)

它由智能构造函数调用
exec :: [a] -> [a] -> [x] -> Queue a
exec f r (_ : s) = Queue f r s
exec f r [] = Queue f' [] f' where
f' = rotate f r []

在每个队列操作之后。智能构造函数总是在 length s = length f - length r + 1 时被调用。 ,确保 rotate 中的模式匹配将会成功。

问题

我讨厌偏函数!我很想找到一种方法来表达类型中的结构不变量。通常的依赖向量似乎是一个可能的选择:
data Nat = Z | S Nat

data Vec n a where
Nil :: Vec 'Z a
Cons :: a -> Vec n a -> Vec ('S n) a

然后(也许)
data Queue a = forall x rl sl . Queue
{ front :: Vec (sl :+ rl) a
, rear :: Vec rl a
, schedule :: Vec sl x
}

问题是我无法弄清楚如何处理这些类型。似乎极有可能有一些 unsafeCoerce将需要使这种效率。但是,我还没有想出一种甚至可以勉强管理的方法。是否有可能在 Haskell 中很好地做到这一点?

最佳答案

这是我得到的:

open import Function
open import Data.Nat.Base
open import Data.Vec

grotate : ∀ {n m} {A : Set}
-> (B : ℕ -> Set)
-> (∀ {n} -> A -> B n -> B (suc n))
-> Vec A n
-> Vec A (suc n + m)
-> B m
-> B (suc n + m)
grotate B cons [] (y ∷ ys) a = cons y a
grotate B cons (x ∷ xs) (y ∷ ys) a = grotate (B ∘ suc) cons xs ys (cons y a)

rotate : ∀ {n m} {A : Set} -> Vec A n -> Vec A (suc n + m) -> Vec A m -> Vec A (suc n + m)
rotate = grotate (Vec _) _∷_

record Queue (A : Set) : Set₁ where
constructor queue
field
{X} : Set
{n m} : ℕ
front : Vec A (n + m)
rear : Vec A m
schedule : Vec X n

open import Relation.Binary.PropositionalEquality
open import Data.Nat.Properties.Simple

exec : ∀ {m n A} -> Vec A (n + m) -> Vec A (suc m) -> Vec A n -> Queue A
exec {m} {suc n} f r (_ ∷ s) = queue (subst (Vec _) (sym (+-suc n m)) f) r s
exec {m} f r [] = queue (with-zero f') [] f' where
with-zero = subst (Vec _ ∘ suc) (sym (+-right-identity m))
without-zero = subst (Vec _ ∘ suc) (+-right-identity m)

f' = without-zero (rotate f (with-zero r) [])
rotate定义为 grotate出于同样的原因 reverse is defined in terms of foldl (或 enumerate in terms of genumerate ):因为 Vec A (suc n + m)不是定义 Vec A (n + suc m) , 而 (B ∘ suc) m定义为 B (suc m) .
exec与您提供的实现相同(以 subst 为模),但我不确定类型: r 可以吗?必须是非空的?

关于haskell - 实时持久队列总数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36611533/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com