小编Mat*_*wik的帖子

如何阅读GHC核心"证据"?

我写了一小部分Haskell来弄清楚GHC如何证明对于自然数,你只能将偶数的一半:

{-# LANGUAGE DataKinds, GADTs, KindSignatures, TypeFamilies #-}
module Nat where

data Nat = Z | S Nat

data Parity = Even | Odd

type family Flip (x :: Parity) :: Parity where
  Flip Even = Odd
  Flip Odd  = Even

data ParNat :: Parity -> * where
  PZ :: ParNat Even
  PS :: (x ~ Flip y, y ~ Flip x) => ParNat x -> ParNat (Flip x)

halve :: ParNat Even -> Nat
halve PZ     = Z
halve …
Run Code Online (Sandbox Code Playgroud)

haskell formal-verification proof ghc haskell-platform

84
推荐指数
1
解决办法
1242
查看次数

如何使catamorphisms与参数化/索引类型一起使用?

我最近学到了一些关于F-algebras的知识:https: //www.fpcomplete.com/user/bartosz/understanding-algebras.我想将此功能提升到更高级的类型(索引和更高级别).此外,我检查了"给Haskell一个促销"(http://research.microsoft.com/en-us/people/dimitris/fc-kind-poly.pdf),这非常有用,因为它给我自己的模糊命名"发明".

但是,我似乎无法创建适用于所有形状的统一方法.

代数需要一些"载体类型",但我们遍历的结构需要一定的形状(本身,递归应用),所以我想出了一个"Dummy"容器,可以携带任何类型,但形状符合预期.然后我使用一个类型系列来耦合它们.

这种方法似乎有效,导致我的'cata'功能的相当通用的签名.

但是,我使用的其他东西(Mu,Algebra)仍然需要为每个形状分别设置版本,只是为了传递一堆类型变量.我希望像PolyKinds这样的东西可以提供帮助(我成功地使用它来塑造虚拟类型),但它似乎只是意味着相反的方式.

由于IFunctor1和IFunctor2没有额外的变量,我试图通过附加(通过类型族)索引保留函数类型来统一它们,但由于存在量化,这似乎是不允许的,所以我留下了多个版本太.

有没有办法统一这两个案例?我是否忽略了一些技巧,或者这只是现在的限制?还有其他可以简化的事情吗?

{-# LANGUAGE DataKinds                 #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE GADTs                     #-}
{-# LANGUAGE PolyKinds                 #-}
{-# LANGUAGE Rank2Types                #-}
{-# LANGUAGE StandaloneDeriving        #-}
{-# LANGUAGE TypeFamilies              #-}
{-# LANGUAGE TypeOperators             #-}
{-# LANGUAGE UndecidableInstances      #-}
module Cata where

-- 'Fix' for indexed types (1 index)
newtype Mu1 f a = Roll1 { unRoll1 :: f (Mu1 f) a }
deriving instance Show (f (Mu1 f) a) …
Run Code Online (Sandbox Code Playgroud)

haskell type-systems algebra gadt catamorphism

12
推荐指数
1
解决办法
747
查看次数

为什么在调用带有按值自取值的方法并同时调用方法的参数时借用移动的值?

我遇到了一个问题,迫使我将一个好的内衬分割成{}带中间层的块let。我根本不清楚这个原因。在这个最小的示例中,我能够找出问题所在:

struct AB {
    a: u8,
    b: u8,
}

impl AB {
    fn foo(&self) -> String {
        String::from("foo")
    }
    fn bar(self, x: String) -> String {
        format!("{} - {} - {}!", x, self.a, self.b)
    }
}

fn main() {
    let x = AB { a: 3, b: 5 };
    let result = x.bar(x.foo());
    println!("{}", result);
}
Run Code Online (Sandbox Code Playgroud)

我的印象是该bar函数的参数将调用之前进行评估bar。在执行期间foo借入x,但在返回时String借用完成,因为String这不是参考轴承x的寿命。当bar …

rust borrow-checker

5
推荐指数
1
解决办法
738
查看次数