4

型変数を参照するコンパイラエラーメッセージを理解しようとしていますp0。ほとんどの場合、エラーメッセージは、コンパイラが何を呼び出しているかを示しp0、「p0は...によってバインドされた剛体型変数です」という行に沿ったものですが、この場合はそうではありません。

一般に、コンパイラのエラーメッセージが(型シグネチャで参照する型変数ではなく)割り当てられた型変数を参照していて、型変数がどこにバインドされているかを教えてくれない場合、どうすればわかりますか?アウト?

{-# LANGUAGE TypeFamilies, FlexibleContexts, MultiParamTypeClasses #-}
import Data.List (minimumBy)
import Data.Ord (comparing)
import qualified Math.Geometry.Grid as G (Grid(..))
import qualified Math.Geometry.GridMap as GM (GridMap(..))
import Prelude hiding (lookup)

class Pattern p where
  type Metric p
  difference ∷ p → p → Metric p
  makeSimilar ∷ p → Metric p → p → p

data SOM gm k p = SOM
  {
    sGridMap :: gm p,
    sLearningFunction :: Int -> Int -> Metric p,
    sCounter :: Int
  }

foo 
  :: (Pattern p, Ord v, v ~ Metric p, GM.GridMap gm p, GM.GridMap gm v, 
      k ~ G.Index (GM.BaseGrid gm p), k ~ G.Index (GM.BaseGrid gm v)) => 
    SOM gm k p -> p -> [(k, v)]
foo s p = GM.toList . GM.map (p `difference`) . sGridMap $ s

bar :: (Pattern p, Ord v, v ~ Metric p) => [(k, v)] -> k
bar ds = fst . minimumBy (comparing snd) $ ds

wombat
  :: (Pattern p, Ord v, v ~ Metric p, GM.GridMap gm p, GM.GridMap gm v,
      k ~ G.Index (GM.BaseGrid gm p), k ~ G.Index (GM.BaseGrid gm v)) => 
    SOM gm k p -> p -> (k, [(k, v)])
wombat s p = (bar diffs, diffs)
  where diffs = foo s p

エラーは次のとおりです。

λ> :l ../amy.hs
[1 of 1] Compiling Main             ( ../amy.hs, interpreted )

../amy.hs:33:19:
    Could not deduce (v ~ Metric p0)
    from the context (Pattern p,
                      Ord v,
                      v ~ Metric p,
                      GM.GridMap gm p,
                      GM.GridMap gm v,
                      k ~ G.Index (GM.BaseGrid gm p),
                      k ~ G.Index (GM.BaseGrid gm v))
      bound by the type signature for
                 wombat :: (Pattern p, Ord v, v ~ Metric p, GM.GridMap gm p,
                            GM.GridMap gm v, k ~ G.Index (GM.BaseGrid gm p),
                            k ~ G.Index (GM.BaseGrid gm v)) =>
                           SOM gm k p -> p -> (k, [(k, v)])
      at ../amy.hs:(30,10)-(32,40)
      `v' is a rigid type variable bound by
          the type signature for
            wombat :: (Pattern p, Ord v, v ~ Metric p, GM.GridMap gm p,
                       GM.GridMap gm v, k ~ G.Index (GM.BaseGrid gm p),
                       k ~ G.Index (GM.BaseGrid gm v)) =>
                      SOM gm k p -> p -> (k, [(k, v)])
          at ../amy.hs:30:10
    In the expression: bar diffs
    In the expression: (bar diffs, diffs)
    In an equation for `wombat':
        wombat s p
          = (bar diffs, diffs)
          where
              diffs = foo s p
Failed, modules loaded: none.
4

1 に答える 1

6

これは少し推測ですが、ここに行きます:

p0の型アノテーションから名前が変更されpました。bar

bar :: (Pattern p, Ord v, v ~ Metric p) => [(k, v)] -> k

ここでpは、の左側でのみ発生し=>ます。とのみkvコールサイトから推測できます。pに与えられたときに同じ結果をもたらす多くの型が存在する可能性があり、コンパイラーは、両方の場合で同じであっても、 inがinと同じであるとMetric想定することはできません。pbarpwombatMetric p

この場合、型署名を次のように変更します

bar :: Ord v => [(k, v)] -> k

他の制約を使用しbarないように。

実際のコードで他の制約を使用する場合bar 、タイプチェッカーを支援するためにプロキシ引数p(適切なタイプの値が存在する場合はタイプである可能性があります)を追加します。wombata -> pp -> a

于 2013-03-25T12:32:42.563 に答える