couldn't match expected type (newtype) - haskell

I'm working on a function
createTypeBoard :: (Int, Int) -> CellType -> Board
using these types
newtype Board = Board [(Cell, CellType)] deriving(Eq)
data CellType = Mine
| Flag
| Void
| Enumerated Int
| Undiscovered
deriving Eq
type Cell = (Int, Int)
createTypeBoard (2,2) Mine should be: Board [((1,1), X), ((1,2), X), ((2,1), X), ((2,2), X)]
(X is the show instance of Mine)
my idea was to use zip:
createTypeBoars (a, b) c = zip (createCells (a, b)) [c]
but I keep getting an error
• Couldn't match expected type ‘Board’
with actual type ‘[(Cell, CellType)]’
• In the expression: zip (createCells (a, b)) [Flag]
In an equation for ‘createTypeBoard’:
createTypeBoard (a, b) Flag = zip (createCells (a, b)) [Flag]
Board basically is [(Cell, CellType)] so I don't really get what the problem is :(

You declared Board with newtype, but you're trying to use it as if you declared it with type. Two choices to fix it:
Declare board like this instead: type Board = [(Cell, CellType)]
Use the Board data constructor in createTypeBoard, like this: createTypeBoard (a, b) c = Board $ zip (createCells (a, b)) [c]
For more information on the difference between type and newtype, which may affect your decision on which fix to go with, see Haskell type vs. newtype with respect to type safety and/or The difference between type and newtype in Haskell.

Related

Generics : run-time ADT for types with instances

Is it possible with Haskell / GHC, to extract an algebraic data type representing all types with Eq and Ord instances ? This would probably need Generics, Typeable, etc.
What I would like is something like :
data Data_Eq_Ord = Data_String String
| Data_Int Int
| Data_Bool Bool
| ...
deriving (Eq, Ord)
For all types known to have instances for Eq and Ord. If it makes the solution easier, we can limit our scope to Ord instances, since Eq is implied by Ord. But is would be interesting to know if constraints intersection is possible.
This data type would be useful because it gives the possibility to use it where Eq and Ord constraints are required, and pattern-match at runtime to refine on types.
I would need this to implement a generic Map Key Value, where Key would be this type, in a Document Indexing library, where the keys and their type is known at run-time. This library is here. For the moment I worked around the issue by defining a data DocIndexKey, and a FieldKey class, but this is not fully satisfactory since it requires boilerplate and can't cover all legit candidates.
Any good alternative approach to this situation is welcome. For some reasons, I prefer to avoid Template Haskell.
Well, it's not an ADT, but this definitely works:
data Satisfying c = forall a. c a => Satisfy a
class (l a, r a) => And l r a where
instance (l a, r a) => And l r a where
ex :: [Satisfying (Typeable `And` Show `And` Ord)]
ex = [ Satisfy (7 :: Int)
, Satisfy "Hello"
, Satisfy (5 :: Int)
, Satisfy [10..20 :: Int]
, Satisfy ['a'..'z']
, Satisfy ((), 'a')]
-- An example of use, with "complicated" logic
data With f c = forall a. c a => With (f a)
-- vvvvvvvvvvvvvvvvvvvvvvvvvv QuantifiedConstraints chokes on this, which is probably a bug...
partitionTypes :: (forall a. c a => TypeRep a) -> [Satisfying c] -> [[] `With` c]
partitionTypes rep = foldr go []
where go (Satisfy x) [] = [With [x]]
go x'#(Satisfy (x :: a)) (xs'#(With (xs :: [b])) : xss) =
case testEquality rep rep :: Maybe (a :~: b) of
Just Refl -> With (x : xs) : xss
Nothing -> xs' : go x' xss
main :: IO ()
main = traverse_ (\(With xs) -> print (sort xs)) $ partitionTypes typeRep ex
Exhaustivity is much harder. Perhaps with a plugin, you could get GHC to do it, but why bother? I don't believe GHC actually tries to keep track of what types it has seen. In particular, you'd have to scan all modules in the project and its dependencies, even those that haven't been loaded by the module containing the type definition. You'd have to implement it from the ground-up. And, as this answer shows, I very much doubt you would actually be able to use such exhaustivity for anything that you can't already do by just taking the open universe as it is.

How do I get 'unpredictable' overloading on a return type working in Haskell?

I have some type instances. Let's call them A, B, and C. They all are instances of typeclass X. Now I would like to create a seperate function create that creates an instance of A, B or C given some input (let's say a string). The type system cannot know what input is going to give what type. That's the thing Haskell doesn't like, and I think I know the answer, but I want to be sure. The current error I'm getting is:
• Couldn't match expected type ‘c’ with actual type ‘GCCCommand’
‘c’ is a rigid type variable bound by
the type signature for:
compiler :: forall c. CompilerCommand c => String -> c
at src/System/Command/Typed/CC.hs:29:1-44
• In the expression: gcc path
In an equation for ‘compiler’:
compiler path
| exe == "g++" || exe == "gcc" || exe == "cc" || exe == "cpp"
= gcc path
where
exe = takeFileName path
• Relevant bindings include
compiler :: String -> c
(bound at src/System/Command/Typed/CC.hs:31:1)
Does that mean, as I suspect, that it is not possible to overload on return type in this particular case because the compiler can't know upfront how the data will look in memory? How would you go to implement this function? I was thinking about creating something like the following:
data SuperX = SuperA A | SuperB B | SuperC C
create :: String -> SuperX
-- create can now be implemented
instance X SuperX where
-- a lot of boilerplate code ...
However, the boilerplate code suggests that it can be done better. Is this really the best way for doing it?
It depends what you need to do with it.
If your later processing doesn't care if it gets an A, a B, or C, just that it gets something that implements X...
restOfProgram :: X a => a -> ThingIWantToCompute
Then you could use continuation passing:
parseABC :: (X a => a -> r) -> String -> Maybe r
parseABC f "A" = Just (f A)
parseABC f ('B':xs) = Just (f (B xs))
parseABC f ('C':xs) = Just (f (C (read xs)))
parseABC _ _ = Nothing
Or an existential data wrapper:
data SomeX where
SomeX :: X t => t -> SomeX
parseABC :: String -> Maybe SomeX
parseABC "A" = Just (SomeX A)
parseABC ('B':xs) = Just (SomeX (B xs))
parseABC ('C':xs) = Just (SomeX (C (read xs)))
parseABC _ _ = Nothing
restOfProgram' :: SomeX -> ThingIWantToCompute
restOfProgram' (SomeX t) = restOfProgram t
If the later processing has different paths for A, B or C, you probably want to return a sum type like SuperX.

How to use the same record selector two ways within a function? Lenses?

I have some data that have different representations based on a type parameter, a la Sandy Maguire's Higher Kinded Data. Here are two examples:
wholeMyData :: MyData Z
wholeMyData = MyData 1 'w'
deltaMyData :: MyData Delta
deltaMyData = MyData Nothing (Just $ Left 'b')
I give some of the implementation details below, but first the actual question.
I often want to get a field of the data, usually via a local definition like:
let x = either (Just . Left . myDataChar) myDataChar -- myDataChar a record of MyData
It happens so often I would like to make a standard combinator,
getSubDelta :: ( _ -> _ ) -> Either a b -> Maybe (Either c d)
getSubDelta f = either (Just . Left . f) f
but filling in that signature is problematic. The easy solution is to just supply the record selector function twice,
getSubDelta :: (a->c) -> (b->d) -> Either a b -> Maybe (Either c d)
getSubDelta f g = either (Just . Left . f) g
but that is unseemly. So my question. Is there a way I can fill in the signature above? I'm assuming there is probably a lens based solution, what would that look like? Would it help with deeply nested data? I can't rely on the data types always being single constructor, so prisms? Traversals? My lens game is weak, so I was hoping to get some advice before I proceed.
Thanks!
Some background. I defined a generic method of performing "deltas", via a mix of GHC.Generics and type families. The gist is to use a type family in the definition of the data type. Then, depending how the type is parameterized, the records will either represent whole data or a change to existing data.
For instance, I define the business data using DeltaPoints.
MyData f = MyData { myDataInt :: DeltaPoint f Int
, myDataChar :: DeltaPoint f Char} deriving Generic
The DeltaPoints are implemented in the library, and have different forms for Delta and Z states.
data DeltaState = Z | Delta deriving (Show,Eq,Read)
type family DeltaPoint (st :: DeltaState) a where
DeltaPoint Z a = a
DeltaPoint Delta a = Maybe (Either a (DeltaOf a))
So a DeltaPoint Z a is just the original data, a, and a DeltaPoint Delta a, may or may not be present, and if it is present will either be a replacement of the original (Left) or an update (DeltaOf a).
The runtime delta functionality is encapsulated in a type class.
class HasDelta a where
type DeltaOf a
delta :: a -> a -> Maybe (Either a (DeltaOf a))
applyDeltaOf :: a -> DeltaOf a -> Maybe a
And with the use of Generics, I can usually get the delta capabilities with something like:
instance HasDelta (MyData Z) where
type (DeltaOf (MyData Z)) = MyData Delta
I think you probably want:
{-# LANGUAGE RankNTypes #-}
getSubDelta :: (forall f . (dat f -> DeltaPoint f fld))
-> Either (dat Z) (dat Delta)
-> Maybe (Either (DeltaPoint Z fld) (DeltaOf fld))
getSubDelta sel = either (Just . Left . sel) sel
giving:
x :: Either (MyData Z) (MyData Delta)
-> Maybe (Either (DeltaPoint Z Char) (DeltaOf Char))
x = getSubDelta myDataChar
-- same as: x = either (Just . Left . myDataChar) myDataChar

Binary instance for Static Pointers

I have the following data type
data Foo a b = A (StaticPtr (a -> b)) deriving (Generic, Typeable)
I want to generate the Binary instance for this type so I can use this function on a remote node.
However, using automatic Binary instantiation doesn't work here:
instance (Binary a, Binary b) => Binary (Foo a b)
This results in
• Could not deduce (Binary (StaticPtr (a -> b)))
arising from a use of ‘binary-0.8.5.1:Data.Binary.Class.$dmput’
from the context: (Binary a, Binary b)
bound by the instance declaration
at /Users/abhiroop/Haskell/snape/app/Spec.hs:23:10-49
• In the expression:
binary-0.8.5.1:Data.Binary.Class.$dmput #Foo a b
In an equation for ‘binary-0.8.5.1:Data.Binary.Class.put’:
binary-0.8.5.1:Data.Binary.Class.put
= binary-0.8.5.1:Data.Binary.Class.$dmput #Foo a b
In the instance declaration for ‘Binary (Foo a b)’
• Could not deduce (Binary (StaticPtr (a -> b)))
arising from a use of ‘binary-0.8.5.1:Data.Binary.Class.$dmget’
from the context: (Binary a, Binary b)
bound by the instance declaration
at /Users/abhiroop/Haskell/snape/app/Spec.hs:23:10-49
• In the expression:
binary-0.8.5.1:Data.Binary.Class.$dmget #Foo a b
In an equation for ‘binary-0.8.5.1:Data.Binary.Class.get’:
binary-0.8.5.1:Data.Binary.Class.get
= binary-0.8.5.1:Data.Binary.Class.$dmget #Foo a b
In the instance declaration for ‘Binary (Foo a b)’
How do I auto generate the Binary instance here?
You can serialize a StaticPtr as a Fingerprint via staticKey and deserialize it via unsafeLookupStaticPtr below it.
You can't define a Binary instance for StaticPtr (even if you wrap it in a newtype to avoid orphans) because the lookup cannot be done purely. But you can still define and use the serializer and deserializer as regular, nonoverloaded functions.
Li-yao Xia's answer is correct. But I had to change my data types, in general, to pass them remotely. I am writing my changes here so it might be useful if someone wants to send a function remotely, there isn't many resources on this online.
So instead of having
data Foo a b = A (StaticPtr (a -> b))
I have changed my data types to look like this:
data Foo a b = A (a -> b)
or to simplify
data Foo f = A f
Here f is the function I want to send remotely.
So taking a simple example of a function like (+ 1) and imagine I want to map this over a list [1,2,3] which is present remotely. My code becomes like this:
main :: IO [Int]
main = do
let list = [1,2,3]
a = static (A (+ 1)) :: StaticPtr (Foo (Int -> Int))
t = staticKey a
-- assuming you sent t to the remote node
-- code on the remote node
x <- unsafeLookupStaticPtr t
case x of
Just sptr -> case deRefStaticPtr sptr of
A f -> return $ map f list
_ -> error "Task undefined"
Nothing -> error "Wrong function serialized"

How do you apply function constraints in instance methods in Haskell?

I'm learning how to use typeclasses in Haskell.
Consider the following implementation of a typeclass T with a type constrained class function f.
class T t where
f :: (Eq u) => t -> u
data T_Impl = T_Impl_Bool Bool | T_Impl_Int Int | T_Impl_Float Float
instance T T_Impl where
f (T_Impl_Bool x) = x
f (T_Impl_Int x) = x
f (T_Impl_Float x) = x
When I load this into GHCI 7.10.2, I get the following error:
Couldn't match expected type ‘u’ with actual type ‘Float’
‘u’ is a rigid type variable bound by
the type signature for f :: Eq u => T_Impl -> u
at generics.hs:6:5
Relevant bindings include
f :: T_Impl -> u (bound at generics.hs:6:5)
In the expression: x
In an equation for ‘f’: f (T_Impl_Float x) = x
What am I doing/understanding wrong? It seems reasonable to me that one would want to specialize a typeclass in an instance by providing an accompaning data constructor and function implementation. The part
Couldn't match expected type 'u' with actual type 'Float'
is especially confusing. Why does u not match Float if u only has the constraint that it must qualify as an Eq type (Floats do that afaik)?
The signature
f :: (Eq u) => t -> u
means that the caller can pick t and u as wanted, with the only burden of ensuring that u is of class Eq (and t of class T -- in class methods there's an implicit T t constraint).
It does not mean that the implementation can choose any u.
So, the caller can use f in any of these ways: (with t in class T)
f :: t -> Bool
f :: t -> Char
f :: t -> Int
...
The compiler is complaining that your implementation is not general enough to cover all these cases.
Couldn't match expected type ‘u’ with actual type ‘Float’
means "You gave me a Float, but you must provide a value of the general type u (where u will be chosen by the caller)"
Chi has already pointed out why your code doesn't compile. But it's not even that typeclasses are the problem; indeed, your example has only one instance, so it might just as well be a normal function rather than a class.
Fundamentally, the problem is that you're trying to do something like
foobar :: Show x => Either Int Bool -> x
foobar (Left x) = x
foobar (Right x) = x
This won't work. It tries to make foobar return a different type depending on the value you feed it at run-time. But in Haskell, all types must be 100% determined at compile-time. So this cannot work.
There are several things you can do, however.
First of all, you can do this:
foo :: Either Int Bool -> String
foo (Left x) = show x
foo (Right x) = show x
In other words, rather than return something showable, actually show it. That means the result type is always String. It means that which version of show gets called will vary at run-time, but that's fine. Code paths can vary at run-time, it's types which cannot.
Another thing you can do is this:
toInt :: Either Int Bool -> Maybe Int
toInt (Left x) = Just x
toInt (Right x) = Nothing
toBool :: Either Int Bool -> Maybe Bool
toBool (Left x) = Nothing
toBool (Right x) = Just x
Again, that works perfectly fine.
There are other things you can do; without knowing why you want this, it's difficult to suggest others.
As a side note, you want to stop thinking about this like it's object oriented programming. It isn't. It requires a new way of thinking. In particular, don't reach for a typeclass unless you really need one. (I realise this particular example may just be a learning exercise to learn about typeclasses of course...)
It's possible to do this:
class Eq u => T t u | t -> u where
f :: t -> u
You need FlexibleContextx+FunctionalDepencencies and MultiParamTypeClasses+FlexibleInstances on call-site. Or to eliminate class and to use data types instead like Gabriel shows here

Resources