I am getting a compiler error for the Applicative instantiation of Safeness, as follows:
{-# LANGUAGE InstanceSigs #-}
module Main where
main :: IO ()
main = pure ()
data Safeness a
= Unsafe a
| Safe a
| VerySafe a
deriving (Eq, Show)
instance Functor Safeness where
fmap :: (a -> b) -> Safeness a -> Safeness b
fmap f (Unsafe x) = Unsafe $ f x
fmap f (Safe x) = Safe $ f x
fmap f (VerySafe x) = VerySafe $ f x
instance Applicative Safeness where
pure :: a -> Safeness a
pure x = Safe x
(<*>) :: Safeness (a -> b) -> Safeness a -> Safeness b
(<*>) (Safe f) (Safe x) = Safe $ f x
(<*>) (VerySafe f) (VerySafe x) = VerySafe $ f x
(<*>) _ x = x
Compiler error:
* Couldn't match type `a' with `b'
`a' is a rigid type variable bound by
the type signature for:
(<*>) :: forall a b. Safeness (a -> b) -> Safeness a -> Safeness b
at C:\practise\app\Main.hs:27:14-58
`b' is a rigid type variable bound by
the type signature for:
(<*>) :: forall a b. Safeness (a -> b) -> Safeness a -> Safeness b
at C:\practise\app\Main.hs:27:14-58
Expected type: Safeness b
Actual type: Safeness a
* In the expression: x
In an equation for `<*>': (<*>) _ x = x
In the instance declaration for `Applicative Safeness'
* Relevant bindings include
x :: Safeness a
(bound at C:\practise\app\Main.hs:30:13)
(<*>) :: Safeness (a -> b) -> Safeness a -> Safeness b
(bound at C:\practise\app\Main.hs:28:5)
|
30 | (<*>) _ x = x
|
I understand that b doesn't have to be the same as a, but it could; and I am always forcing it to be the same in a certain case. What is wrong with that, and how else can I code this for the intended functionality?