Просьба.

Jan 04, 2012 19:18

Тут у меня код получился, который должен работать, но не работает.


{-# LANGUAGE GADTs, TypeFamilies, MultiParamTypeClasses, TypeOperators #-}
{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances, EmptyDataDecls #-}

import Control.Monad
import Control.Monad.State

-------------------------------------------------------------------------------
-- Home brewn HList.

data Nil

infixr 5 :.
data a :. b

class FAIL a -- no instances!

-------------------------------------------------------------------------------
-- Monad.

type M as a = StateT as IO a

getAnalysisResult :: EnabledAnalysis a as => a -> M as Int
getAnalysisResult _ = error "getAnalysisResult!!!"

setAnalysisResult :: EnabledAnalysis a as => a -> Int -> M as ()
setAnalysisResult _ _ = error "setAnalysisResult!!!"

-------------------------------------------------------------------------------
-- Analysis classes.

-- |Analysis called for
class (Analyses (RequiresAnalyses a)) => Analysis a where
-- |What has to be done before our pass.
type RequiresAnalyses a

-- |Perform an analysis.
perform :: (EnabledAnalysis a as, EnabledAnalyses (RequiresAnalyses a) as) =>
a -> M as ()

-- |HList of analyses.
class Analyses as where

instance Analyses Nil where

instance (Analysis a, Analyses as) => Analyses (a :. as) where

data AnalysisNotEnabled a

class EnabledAnalysis a as

instance (FAIL (AnalysisNotEnabled a)) => EnabledAnalysis a Nil
instance (Analysis a, Analyses as) => EnabledAnalysis a (a :. as)
instance (Analysis a, Analysis a', EnabledAnalysis a as) => EnabledAnalysis a (a' :. as)

class EnabledAnalyses as eas

instance EnabledAnalyses Nil eas
instance (EnabledAnalyses as eas, EnabledAnalysis a eas) => EnabledAnalyses (a :. as) eas

-------------------------------------------------------------------------------
-- Analysis instances.

data Base = Base

instance Analysis Base where
type RequiresAnalyses Base = Nil
perform a = do
x <- getAnalysisResult a
setAnalysisResult a (x+1)

data Derived = Derived

instance Analysis Derived where
type RequiresAnalyses Derived = Base :. Nil
perform a = do
x <- getAnalysisResult a
y <- getAnalysisResult Base
setAnalysisResult a (x+y)

По идее, контекст (EnabledAnalysis a as, EnabledAnalyses (RequiresAnalyses a) as) функции perform должен раскрываться, но не раскрывается.

В результате получается ошибка:
Prelude> :r
[1 of 1] Compiling Main ( a.hs, interpreted )

a.hs:78:22:
Could not deduce (EnabledAnalysis Base as)
arising from a use of `getAnalysisResult'
from the context (EnabledAnalysis Derived as,
EnabledAnalyses (RequiresAnalyses Derived) as)
bound by the type signature for
perform :: (EnabledAnalysis Derived as,
EnabledAnalyses (RequiresAnalyses Derived) as) =>
Derived -> M as ()
at a.hs:(76,9)-(79,41)
Possible fix:
add (EnabledAnalysis Base as) to the context of
the type signature for
perform :: (EnabledAnalysis Derived as,
EnabledAnalyses (RequiresAnalyses Derived) as) =>
Derived -> M as ()
or add an instance declaration for (EnabledAnalysis Base as)
In a stmt of a 'do' expression: y <- getAnalysisResult Base
In the expression:
do { x <- getAnalysisResult a;
y <- getAnalysisResult Base;
setAnalysisResult a (x + y) }
In an equation for `perform':
perform a
= do { x <- getAnalysisResult a;
y <- getAnalysisResult Base;
setAnalysisResult a (x + y) }
Failed, modules loaded: none.

Ошибка получается с ghc 6.12.1, 7.0.4. Если у кого есть 7.2 или 7.4 - попробуйте, пожалуйста. Вдруг у вас ошибки не будет.

строгая типизация, ошибки, Хаскель

Previous post Next post
Up