2016-05-03 10 views
2

インターフェイスで制約された型の関数を作成したいと思います。私の目的は、VerifiedMonoidClasses.Verifiedのcontribパッケージから定義して、単純なモノイドソルバーを構築することです。Idrisインターフェイスで関数型を制約する

eval : VerifiedMonoid a => Expr n -> Env a n -> a 

私は愚かな何かをするか、何かが欠けています:evalの型シグネチャのため

Monoid-prover.idr line 29 col 5: 
When checking type of MonoidProver.eval: 
Can't find implementation for VerifiedMonoid a 

イドリスは私に次のエラーを与えますか?そのような制約付きの型(evalの型のような)は、Haskellの型のように解釈できますか?

完全なコードを以下に示します。

module MonoidProver 

import Classes.Verified 

import Data.Fin 
import Data.Vect 

%default total 

infixl 5 :+: 

data Expr : Nat -> Type where 
    Var : Fin n -> Expr n 
    Id : Expr n 
    (:+:) : Expr n -> Expr n -> Expr n 

Env : VerifiedMonoid a => (a : Type) -> Nat -> Type 
Env a n = Vect n a 

eval : VerifiedMonoid a => Expr n -> Env a n -> a 
eval (Var i) env = index i env 
eval Id  env = neutral 
eval (e :+: e') env = eval e env <+> eval e' env 
+2

私はあなたのタイプ署名が 'a'を間違ってスコープしていると思います。あなたが与えたタイプは' Env:VerifiedMonoid a =>(b:タイプ) - > Nat-> Type'に相当します。また、 'Env'の' VerifiedMonoid'制約はあなたを買うはずのものは何ですか? 'Env'の署名から削除すると、あなたのコードが型チェックされます。 – Cactus

答えて

1

@Cactusコメントで述べたように、ここでの問題は、Envのための型シグネチャが正しくないということです。具体的には、制約は引数の値に依存するため、依存型(pi)型であり、依存型は左から右へ(それらが使用される前に導入されるように)強制されます。私の理解では、基本的にコンパイラは、x : a\Pi_{(x\;:\;a)}B(x)の省略形として見ています。ここで、B(x)は、量子の右側の型シグネチャの一部です。つまり、(a : Type)は実際には新鮮なaをバインドします。これは、暗黙的に普遍的にバインドされているVerifiedMonoid a制約で使用されていたものと同じではありません(a)。幸いにも

、イドリスはハスケル(ここで、すべてのタイプのクラス制約は型シグネチャの先頭になければならない)ではないので、これは修正するのは簡単です:ちょうどEnv : (a : Type) -> VerifiedMonoid a => Nat -> Typeにあなたの型シグネチャを変更、aは、その前にバインドされているように、使用されている!

関連する問題