У меня есть следующая структура в haskell, которая реализует некоторые механизмы для печати и вызывает унификатор. Я получаю следующую ошибку от main:
0 =/= int
Кажется, что 0 - это число, а не переменная. Ниже приведена полная реализация.
data CType
= CVar Int
| CArr CType CType
| CInt
| CBool
deriving (Eq, Data)
data Constraint
= Equality CType CType
deriving (Eq, Data)
У меня есть несколько базовых типов (int и bool), тип стрелки и переменные типа. Затем я запускаю некоторые алгоритмы, которые генерируют ограничения равенства, которые представлены выше.
Моя цель состоит в том, что, имея список ограничений, я хочу найти наиболее общий унификатор.
Я наткнулся на эту библиотеку: http://hackage.haskell.org/package/compdata-0.1/docs/Data-Comp-Unification.html
Поскольку я новичок в Haskell, я не могу сразу понять, могу ли я применить его напрямую. Могу ли я использовать эту библиотеку или мне рекомендуется написать унификатор с нуля?
ОБНОВЛЕНИЕ
В настоящее время я вношу следующие изменения в код, но получаю ошибку объединения для уравнения
f=g
module SolveEq where
import Data.Data
import Data.Void
import Data.List as List
import Data.Map as Map
import Data.Set as Set
import Data.Maybe (fromJust)
import Data.Maybe (isJust)
import Control.Monad
import TypeCheck
import Data.Comp.Variables
import Data.Comp.Unification
import Data.Comp.Term
import Data.Comp.Derive
import Constraint
import Lang
data CTypeF a
= CVarF Int
| CArrF a a
| CIntF
| CBoolF
deriving (Data, Functor, Foldable, Traversable, Show, Eq)
$(makeShowF ''CTypeF)
example :: String
example = showF (CIntF :: CTypeF String)
instance HasVars CTypeF Int where
isVar (CVarF x) = Just x
isVar (CArrF x y) = Nothing
isVar CIntF = Nothing
isVar CBoolF = Nothing
type CType_ = Term CTypeF
f :: CType_
f = Term (CVarF 0)
g :: CType_
g = Term CIntF
unravel :: CType_ -> CType
unravel a =
case unTerm a of
CVarF i -> CVar i
CArrF a b -> CArr (unravel a) (unravel b)
CIntF -> CInt
CBoolF -> CBool
getUnify :: Either (UnifError CTypeF Int) (Subst CTypeF Int)
getUnify = unify [(f,g)]
main = case getUnify of
Left (FailedOccursCheck v term) -> putStrLn ("failed occurs check " ++ show v ++ ": " ++ (show $ unravel term))
Left (HeadSymbolMismatch t1 t2) -> putStrLn ("head symbol mismatch " ++ show (unravel t1) ++ " =/= " ++ (show $ unravel t2))
Left (UnifError str) -> putStrLn str
Right (subst :: Subst CTypeF Int) -> print (fmap unravel subst)
Проблема заключается в unify [(f,g)]
, который, как я ожидал, сопоставит 0 с Int. Но вроде не видит, что 0 это переменная. Возможно, что-то не так с моим isVar?
Примечание. Я использую compdata-0.12.
Constraint
из-за возможной путаницы с типConstraint
, встроенный в GHC - person Joseph Sible-Reinstate Monica   schedule 17.06.2019isVar
внутри вашего экземпляраHasVars
. Это должно исправить это. - person user11228628   schedule 17.06.2019