I'm trying to use undefined to get value of type constant (something like sizeOf in storable).
module Main where
class MyClass a where
typeConst :: a -> String
-- ^ Argument is ignored
class TryRead a where
tryRead :: String -> Maybe a
newtype ByLen a = ByLen a
-- | Make all types under ByLen readable, if their typeConst's are longer then 3 characters
instance (Read a, MyClass a) => TryRead (ByLen a) where
tryRead = if len > 3
then Just . ByLen . read
else const Nothing
where
len = length $ typeConst (undefined :: a)
instance MyClass Int where
typeConst = const "moreThan3"
main :: IO ()
main = go (tryRead "214234" :: Maybe (ByLen Int))
where
go Nothing = print "Nothing :("
go (Just (ByLen i)) = print i
However, this gives an error:
Could not deduce (MyClass a0) arising from a use of ‘typeConst’
from the context (Read a, MyClass a)
bound by the instance declaration at src/Main.hs:13:10-49
The type variable ‘a0’ is ambiguous
Note: there is a potential instance available:
instance MyClass Int -- Defined at src/Main.hs:20:10
In the second argument of ‘($)’, namely
‘typeConst (undefined :: a)’
In the expression: length $ typeConst (undefined :: a)
In an equation for ‘len’: len = length $ typeConst (undefined :: a)
I don't understand what problem with type deducing is there, considering I specified type for typeConst argument explicitly as a type variable, which is bound by MyClass a, so it should in my mind have no problems applying to typeConst function.
ScopedTypeVariablesextension: otherwise theain thewhereclause is not recognized as being the same one as the one bound before but rather a fresh type variable (hence thea0vs.aissue).forall? (I tried something like that inside non-class function and it didn't. compile until I added aforall)instance forall a. (...) => MyClass (Maybe a)for instance then you get aMalformed instanceerror.