我尝试使用undefined来获取类型常量的值(类似于sizeOf
的值)。
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
然而,这会产生错误:
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)
我不明白类型推断的问题是什么,考虑到我将typeConst
参数的类型明确指定为a
类型变量,它由MyClass a
绑定,所以在我看来,应用typeConst
函数没有问题。