Converting Haskell code to Agda
agda, haskell
Solution
Let's compare `BoolProp` declaration in Haskell with the Agda version:
data BoolProp :: * -> * where
-- ...
From Haskell's point of view, `BoolProp` is a unary type constructor (which roughly means: give me a concrete type `*` and I give you concrete type back).
In the constuctors, `BoolProp` alone would make no sense - it's not a type! You have to give it a type first (`TRUE` in case of `PTrue`, for example).
In your Agda code, you state that `BoolProp` lies in `Set` (which is something like `*` in Haskell). But your constructors tell a different story.
ptrue : BoolProp true
By applying `BoolProp` to `true`, you're telling that `BoolProp` should take a `Bool` argument and give back a `Set` (i.e. `Bool → Set`). But you just said that `BoolProp` is in `Set`!
Obviously, because `Bool → Set ≠ Set`, Agda complains.
The correction is rather simple:
data BoolProp : Bool → Set where
-- ...
And now because `BoolProp true : Set`, everything's fine and Agda is happy.
You could actually make the Haskell code a bit nicer and you'd see the problem right away!
{-# LANGUAGE GADTs, KindSignatures, DataKinds, TypeFamilies #-}
module Main where
type family And (a :: Bool) (b :: Bool) :: Bool
type instance And True b = b
type instance And False b = False
type family Or (a :: Bool) (b :: Bool) :: Bool
type instance Or True b = True
type instance Or False b = b
type family Not (a :: Bool) :: Bool
type instance Not True = False
type instance Not False = True
data BoolProp :: Bool -> * where
PTrue :: BoolProp True
PFalse :: BoolProp False
PAnd :: BoolProp a -> BoolProp b -> BoolProp (And a b)
POr :: BoolProp a -> BoolProp b -> BoolProp (Or a b)
PNot :: BoolProp a -> BoolProp (Not a)
Problem
We have to convert this haskell data type into agda code: ``` data TRUE data FALSE data BoolProp :: * -> * where PTrue :: BoolProp TRUE PFalse :: BoolProp FALSE PAnd :: BoolProp a -> BoolProp b -> BoolProp (a `AND` b) POr :: BoolProp a -> BoolProp b -> BoolProp (a `OR` b) PNot :: BoolProp a -> BoolProp (NOT a) ``` This is what I have so far: ``` module BoolProp where open import Data.Bool open import Relation.Binary.PropositionalEquality data BoolProp : Set wheree ptrue : BoolProp true pfalse : BoolProp false pand : (X Y : Bool) -> BoolProp X -> BoolProp Y -> BoolProp (X ? Y) por : (X Y : Bool) -> BoolProp X -> BoolProp Y -> BoolProp (X ? Y) pnot : (X : Bool) -> BoolProp X -> BoolProp (not X) ``` But I'm getting this error: "Set should be a function type, but it isn't when checking that true are valid arguments to a function of type Set". I'm thinking that Set needs to be changed to something else, but I'm confused as to what this should be.