I have the following structure in haskell, which implements some machinery for printing and calls the unifier. I get the following error from main:
0 =/= int
It seems to think that 0 is a number rather than a variable. Below is the full implementation.
data CType
= CVar Int
| CArr CType CType
| CInt
| CBool
deriving (Eq, Data)
data Constraint
= Equality CType CType
deriving (Eq, Data)
I have some base types (int and bool), an arrow type, and type variables. Then I am running some algorithms that generate equality constraints which are represented in the way above.
My goal is that given a list of constraints, I want to find the most general unifier.
I came across this library: http://hackage.haskell.org/package/compdata-0.1/docs/Data-Comp-Unification.html
Since I am new to Haskell, I can't immediately figure out if I can directly apply it. Could I use this library or am I recommended to write the unifier from scratch?
UPDATE
I am currently making the following changes to the code, but am getting a unification error for the equation
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)
The issue is in unify [(f,g)] which I would have expected to map 0 to Int. But it seems to not see that 0 is a variable. Is there something wrong with my isVar possibly?
Note: I am running with compdata-0.12