Using haskell read and typeclasses - ambiguous type variable error - haskell

I have an ambiguous type variable error on the definition of "trial" below, I am wondering if there is anything that can be done to make this situation work? I want to really just deal with instances and not explicit data types (such as the MO1, MO2 included below).
module Tc102 where
class (Show a, Read a) => MyObj a where
alpha :: a->String
beta :: a->Int
data MO1 = MO1 { a1 :: String, b1 :: Int } deriving (Show,Read)
data MO2 = MO2 { a2 :: String, b2 :: Int } deriving (Show,Read)
instance MyObj MO1 where
alpha = a1
beta = b1
instance MyObj MO2 where
alpha = a2
beta = b2
a = MO1 "a" 3
b = MO2 "b" 4
test :: MyObj a => a->String
test = alpha
showMe :: (MyObj a)=> a -> String
showMe = show
readMe :: (MyObj a) => String -> a
readMe = read
trial :: MyObj a => a -> String
trial = test . readMe . showMe
thanks in advance all! I fear however i might need to go to a helper function that would convert old ADT to the 'latest versions...
Simon
EDIT To clarify, imagine that I first show to a file, then later reload the object. Then the function i have is more like
trial :: String -> Int
trial s = beta x
where x = readMe s

You get the error because the compiler doesn't know what concrete type readMe should return, since all that test requires is that it be an instance of MyObj. It could be MO1, MO2, or something else entirely, and readMe could return any of those.
Assuming you want readMe . showMe to act like id and output the same type given as input, the quick-and-dirty way is to define a function that does just that, and give it a type signature that equates the input and output types:
trial :: MyObj a => a -> String
trial = test . readShowMe
where readShowMe :: MyObj a => a -> a
readShowMe = readMe . showMe
Now the compiler can figure out what concrete type to give to test as input.

You can't read compile-time type from run-time file. You should explicitly implement run-time type-varying value.
As example:
data AnyMyObj = forall a . MyObj a => AnyMyObj a
test :: AnyMyObj -> String
test (AnyMyObj x) = alpha x
showMe :: AnyMyObj -> String
showMe (AnyMyObj x) = show x
readMe :: String -> AnyMyObj
readMe s = AnyMyObj (read s :: MO1) -- maybe something more complicated
trial :: AnyMyObj -> String
trial = test . readMe . showMe

There are fancy tricks to this, and the ultimate answer is indeed to read into some sort of existential. For a fancy exposition of a very powerful/general way to do this, see Oleg's Typed-tagless final lecture notes: http://okmij.org/ftp/tagless-final/course/#type-checking.
But that's serious overkill for an example like yours -- the trickiness generally enters when you have tree structures, and especially when you have tree structures representing lambda terms.
For your purposes, ony's example above is roughly right.
But keep in mind that even though you can create new instances of MyObj, your read function will only be able to read a fixed universe, at least without high-level hackery.
So this is a case where I'd question whether you want a typeclass to begin with, or just more constructors in a single ADT.
data MyObj = MO1 { a1 :: String, b1 :: Int }
| MO2 { a2 :: String, b2 :: Int } deriving (Show,Read)
... for example.

Related

List of a Type Classe instance

I've been playing around with Haskell type classes and I am facing a problem I hope someone could help me to solve. Consider that I come from a Swift background and "trying" to port some of protocol oriented knowledge to Haskell code.
Initially I declared a bunch of JSON parsers which had the same structure, just a different implementation:
data Candle = Candle {
mts :: Integer,
open :: Double,
close :: Double
}
data Bar = Bar {
mts :: Integer,
min :: Double,
max :: Double
}
Then I decided to create a "Class" that would define their basic operations:
class GenericData a where
dataName :: a -> String
dataIdentifier :: a -> Double
dataParsing :: a -> String -> Maybe a
dataEmptyInstance :: a
instance GenericData Candle where
dataName _ = "Candle"
dataIdentifier = fromInteger . mts
dataParsing _ = candleParsing
dataEmptyInstance = emptyCandle
instance GenericData Bar where
dataName _ = "Bar"
dataIdentifier = fromInteger . mts
dataParsing _ = barParsing
dataEmptyInstance = emptyBar
My first code smell was the need to include "a" when it was not needed (dataName or dataParsing) but then I proceded.
analyzeArguments :: GenericData a => [] -> [String] -> Maybe (a, [String])
analyzeArguments [] _ = Nothing
analyzeArguments _ [] = Nothing
analyzeArguments name data
| name == "Candles" = Just (head possibleCandidates, data)
| name == "Bar" = Just (last possibleRecordCandidates, data)
| otherwise = Nothing
possibleCandidates :: GenericData a => [a]
possibleCandidates = [emptyCandle, emptyBar]
Now, when I want to select if either instance should be selected to perform parsing, I always get the following error
• Couldn't match expected type ‘a’ with actual type ‘Candle’
‘a’ is a rigid type variable bound by
the type signature for:
possibleCandidates :: forall a. GenericData a => [a]
at src/GenericRecords.hs:42:29
My objective was to create a list of instances of GenericData because other functions depend on that being selected to execute the correct dataParser. I understand this has something to do with the type class checker, the * -> Constraint, but still not finding a way to solve this conflict. I have used several GHC language extensions but none has solved the problem.
You have a type signature:
possibleCandidates :: GenericData a => [a]
Which you might thing implies that you can put anything in that list as long as it is GenericData. But that is not the way Haskell's type system actually works. The value possibleCandidates can be a list of any type which has a GenericData class but every element of the list must be of the same type.
What the GHC error message is telling you (in its own special way) is that the first element of the list is a Candle so it thinks that the rest of the list should also be of type Candle but the second element is actually a Bar.
Now there are ways to make heterogeneous lists (and other collections) in Haskell, but it is almost never the right thing to do.
One typical solution to this problem is to just merge everything down into one sum data type:
data GenericData = GenericCandle Candle | GenericBar Bar
You could even forgo the step of indirection and just put the Candle and Bar data directly into the data structure.
Now instead f a class you just have a datatype and your class functions become normal functions:
dataName :: GenericData -> String
dataIdentifier :: GenericData -> Double
dataParsing :: GenericData -> String -> Maybe a
dataEmptyInstance :: String -> GenericData
There are some other more complex ways to make this work, but if a sum data type fits the bill, use it. It is very common for parsers in Haskell to have a large sum data type (usually also recursive) as their result. Take a look at the Value type in Aeson the standard JSON library for an example.

How to avoid default return value when accessing a non-existent field with lenses?

I love Lens library and I love how it works, but sometimes it introduces so many problems, that I regret I ever started using it. Lets look at this simple example:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data Data = A { _x :: String, _y :: String }
| B { _x :: String }
makeLenses ''Data
main = do
let b = B "x"
print $ view y b
it outputs:
""
And now imagine - we've got a datatype and we refactor it - by changing some names. Instead of getting error (in runtime, like with normal accessors) that this name does not longer apply to particular data constructor, lenses use mempty from Monoid to create default object, so we get strange results instead of error. Debugging something like this is almost impossible.
Is there any way to fix this behaviour? I know there are some special operators to get the behaviour I want, but all "normal" looking functions from lenses are just horrible. Should I just override them with my custom module or is there any nicer method?
As a sidenote: I want to be able to read and set the arguments using lens syntax, but just remove the behaviour of automatic result creating when field is missing.
It sounds like you just want to recover the exception behavior. I vaguely recall that this is how view once worked. If so, I expect a reasonable choice was made with the change.
Normally I end up working with (^?) in the cases you are talking about:
> b ^? y
Nothing
If you want the exception behavior you can use ^?!
> b ^?! y
"*** Exception: (^?!): empty Fold
I prefer to use ^? to avoid partial functions and exceptions, similar to how it is commonly advised to stay away from head, last, !! and other partial functions.
Yes, I too have found it a bit odd that view works for Traversals by concatenating the targets. I think this is because of the instance Monoid m => Applicative (Const m). You can write your own view equivalent that doesn't have this behaviour by writing your own Const equivalent that doesn't have this instance.
Perhaps one workaround would be to provide a type signature for y, so know know exactly what it is. If you had this then your "pathological" use of view wouldn't compile.
data Data = A { _x :: String, _y' :: String }
| B { _x :: String }
makeLenses ''Data
y :: Lens' Data String
y = y'
You can do this by defining your own view1 operator. It doesn't exist in the lens package, but it's easy to define locally.
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data Data = A { _x :: String, _y :: String }
| B { _x :: String }
makeLenses ''Data
newtype Get a b = Get { unGet :: a }
instance Functor (Get a) where
fmap _ (Get x) = Get x
view1 :: LensLike' (Get a) s a -> s -> a
view1 l = unGet . l Get
works :: Data -> String
works = view1 x
-- fails :: Data -> String
-- fails = view1 y
-- Bug.hs:23:15:
-- No instance for (Control.Applicative.Applicative (Get String))
-- arising from a use of ‘y’

How to store arbitrary values in a recursive structure or how to build a extensible software architecture?

I'm working on a basic UI toolkit and am trying to figure out the overall architecture.
I am considering to use WAI's structure for extensibility. A reduced example of the core structure for my UI:
run :: Application -> IO ()
type Application = Event -> UI -> (Picture, UI)
type Middleware = Application -> Application
In WAI, arbitrary values for Middleware are saved in the vault. I think that this is a bad hack to save arbitary values, because it isn't transparent, but I can't think of a sufficient simple structure to replace this vault to give every Middleware a place to save arbitrary values.
I considered to recursively store tuples in tuples:
run :: (Application, x) -> IO ()
type Application = Event -> UI -> (Picture, UI)
type Middleware y x = (Application, x) -> (Application, (y,x))
Or to only use lazy lists to provide a level on which is no need to separate values (which provides more freedom, but also has more problems):
run :: Application -> IO ()
type Application = [Event -> UI -> (Picture, UI)]
type Middleware = Application -> Application
Actually, I would use a modified lazy list solution. Which other solutions might work?
Note that:
I prefer not to use lens at all.
I know UI -> (Picture, UI) could be defined as State UI Picture .
I'm not aware of a solution regarding monads, transformers or FRP. It would be great to see one.
Lenses provide a general way to reference data type fields so that you can extend or refactor your data set without breaking backwards compatibility. I'll use the lens-family and lens-family-th libraries to illustrate this, since they are lighter dependencies than lens.
Let's begin with a simple record with two fields:
{-# LANGUAGE Template Haskell #-}
import Lens.Family2
import Lens.Family2.TH
data Example = Example
{ _int :: Int
, _str :: String
}
makeLenses ''Example
-- This creates these lenses:
int :: Lens' Example Int
str :: Lens' Example String
Now you can write Stateful code that references fields of your data structure. You can use Lens.Family2.State.Strict for this purpose:
import Lens.Family2.State.Strict
-- Everything here also works for `StateT Example IO`
example :: State Example Bool
example = do
s <- use str -- Read the `String`
str .= s ++ "!" -- Set the `String`
int += 2 -- Modify the `Int`
zoom int $ do -- This sub-`do` block has type: `State Int Int`
m <- get
return (m + 1)
The key thing to note is that I can update my data type, and the above code will still compile. Add a new field to Example and everything will still work:
data Example = Example
{ _int :: Int
, _str :: String
, _char :: Char
}
makeLenses ''Example
int :: Lens' Example Int
str :: Lens' Example String
char :: Lens' Example Char
However, we can actually go a step further and completely refactor our Example type like this:
data Example = Example
{ _example2 :: Example
, _char :: Char
}
data Example2 = Example2
{ _int2 :: Int
, _str2 :: String
}
makeLenses ''Example
char :: Lens' Example Char
example2 :: Lens' Example Example2
makeLenses ''Example2
int2 :: Lens' Example2 Int
str2 :: Lens' Example2 String
Do we have to break our old code? No! All we have to do is add the following two lenses to support backwards compatibility:
int :: Lens' Example Int
int = example2 . int2
str :: Lens' Example Char
str = example2 . str2
Now all the old code still works without any changes, despite the intrusive refactoring of our Example type.
In fact, this works for more than just records. You can do the exact same thing for sum types, too (a.k.a. algebraic data types or enums). For example, suppose we have this type:
data Example3 = A String | B Int
makeTraversals ''Example3
-- This creates these `Traversals'`:
_A :: Traversal' Example3 String
_B :: Traversal' Example3 Int
Many of the things that we did with sum types can similarly be re-expressed in terms of Traversal's. There's a notable exception of pattern matching: it's actually possible to implement pattern matching with totality checking with Traversals, but it's currently verbose.
However, the same point holds: if you express all your sum type operations in terms of Traversal's, then you can greatly refactor your sum type and just update the appropriate Traversal's to preserve backwards compatibility.
Finally: note that the true analog of sum type constructors are Prisms (which let you build values using the constructors in addition to pattern matching). Those are not supported by the lens-family family of libraries, but they are provided by lens and you can implement them yourself using just a profunctors dependency if you want.
Also, if you're wondering what the lens analog of a newtype is, it's an Iso', and that also minimally requires a profunctors dependency.
Also, everything I've said works for reference multiple fields of recursive types (using Folds). Literally anything you can imagine wanting to reference in a data type in a backwards-compatible way is encompassed by the lens library.

What is a clean way to call a function using several Getters from Control.Lens.

Given some data structure with lenses defined, for example:
import Control.Lens
data Thing =
Thing {
_a :: String
, _b :: String
, _c :: Int
, _d :: Int
}
makeLenses ''Thing
And given some function that I want to call using several getters, for example:
fun :: Int -> String -> Int -> String -> Bool
fun = undefined
At the moment, I end up with a lot of ugliness with parens to access each field, for example:
thing = Thing "hello" "there" 5 1
answer = fun (thing^.c) (thing^.a) (thing^.d) (thing^.b)
Given the conciseness of the lens library in most other situations I was hoping for something a little more elegant, but I can't find any combinators that will help this specific case.
Since any lens could be used in either the viewing or the setting "mode", we'll need to at least specify view X for each lens X. But for any lens l :: Lens' a b, view l has a type like a -> b if you translate some of the MonadReader noise.
We can thus get rid of some of the repetition using the Applicative instance for ((->) a).
thing & fun <$> view c <*> view a <*> view d <*> view b

Lens package with algebraic types

I was coding with with the lens package. Everything was going fine until I tried to access a certain field on an algebraic type:
import Control.Lens
data Type = A { _a :: Char } | B
makeLenses ''Type
test1 = _a (A 'a')
test2 = (A 'a') ^. a
No instance for (Data.Monoid.Monoid Char)
arising from a use of `a'
Possible fix:
add an instance declaration for (Data.Monoid.Monoid Char)
In the second argument of `(^.)', namely `a'
In the expression: (A 'a') ^. a
In an equation for `test2': test2 = (A 'a') ^. a
I could just go with _a, but the datatype in my real program is much deeper and I kind of intended on using lens to lower the amount of work I have to do. I have been looking over the lens library but there's so much there, and I'm not sure if he's dealt with this scenario or it is just something the lens library doesn't support.
As a side note, if I actually use a monoid like String for the datatype instead of Char, it then compiles and gives the right answer, I have no idea why.
Edit: After reading hammar's comment, I tried this and this works:
test2 = (A 'a') ^? a
test3 = B ^? a
But it is kind of weird to get a maybe out of that for something that has to exist.
Just so that this is answered, my problem was that I had an algebraic type where some fields were in common between the different constructors but there was a couple fields that weren't shared would die in runtime if I tried to use them.
data Exercise =
BarbellExercise {
name :: String,
weight :: Int,
reps :: Int
} |
BodyWeightExercise {
name :: String,
reps :: Int
}
exer1 = BarbellExercise "Squats" 235 15
exer2 = BarbellExercise "Deadlifts" 265 15
exer3 = BodyWeightExercise "Pullups" 12
exer4 = BarbellExercise "Overhead Press" 85 15
workout = [exer1, exer2, exer3, exer4]
test = do
mapM_ displayExercise workout
where
displayExercise x = putStrLn $ "Exercise: " ++ (name x) ++ " You must perform " ++ (show $ reps x) ++ "#" ++ (show $ weight x)
This compiles but dies runtime if I make the mistake of using the weight function. Understandable mistake. When lenses uses template haskell to generate instances it notices this and changes its behavior to prevent a mistake. You could remove the field accessors but in my case most of the fields were the same between datatypes. Here's how I should have written the data type once I noticed the fields did not match up:
data Exercise =
BarbellExercise
String -- ^ name
Int -- ^ reps
Int -- ^ weight
|
BodyWeightExercise
String -- ^ name
Int -- reps
name :: Exercise -> String
name (BarbellExercise n _ _) = n
name (BodyWeightExercise n _) = n
reps :: Exercise -> Int
reps (BarbellExercise _ r _) = r
reps (BodyWeightExercise _ r) = r
By doing it this way, while it is a little less clean, the error are caught at compile time. By forcing me to write the functions myself I would notice any partial functions as I was writing them.
I do kind of wish ghc would have warned me. It seems like it would be really easy for it to detect such a thing.

Resources