and*_*gps 5 haskell return instance
如果函数的返回是a class ClassA,是否可以在这样的函数中返回任何实例ClassA?例如:someFunction :: (ClassA a) => String -> a
那么,为什么下面的这个功能不起作用?请注意,这String是一个实例Eq
getAnyEq :: (Eq a) => String -> a
getAnyEq input |input == "1" = "something"
|otherwise = "other"
Run Code Online (Sandbox Code Playgroud)
发生的错误是:
Could not deduce (a ~ [Char])
from the context (Eq a)
bound by the type signature for getAnyEq :: Eq a => String -> a
at src/InterceptorRegistry.hs:11:13-33
`a' is a rigid type variable bound by
the type signature for getAnyEq :: Eq a => String -> a
at src/InterceptorRegistry.hs:11:13
Run Code Online (Sandbox Code Playgroud)
我试图在互联网资源上找到这个确切的解释,但我没有找到......你能告诉我一些吗?
Dav*_*ani 11
该类型Eq a => a并不意味着"实现的类型Eq",而是"任何实现的类型Eq.例如,如果使用undefined实现您的函数:
getAnyEq :: (Eq a) => String -> a
getAnyEq str = undefined
Run Code Online (Sandbox Code Playgroud)
以下函数正确编译(尽管在运行时会因未定义的错误而崩溃):
x,y,z :: Bool
x = getAnyEq "test" == "hello"
y = getAnyEq "test" == [Just (Right True)]
z = getAnyEq "test" == ("this", "sss")
Run Code Online (Sandbox Code Playgroud)
由于无法为结果生成值,因此无法对函数进行合理的实现.
只有当类型变量具有包含返回值的函数的类的实例时,才返回类型变量的函数才有意义.例如考虑Num类:
class (Eq a, Show a) => Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
Run Code Online (Sandbox Code Playgroud)
(注意我在ghc的旧版本上测试了这个,你的Num可能没有Eq或Show约束).
该函数fromInteger返回a(不需要a输入),因此我们可以a从该类型类中获取.有值后,可以使用其他功能.所以以下功能有效:
getANum:: (Num a) => String -> a
getANum "zero" = fromInteger 0
getANum "asdf" = fromInteger 46
getANum _ = fromInteger 1
> getANum "asdf"
46
Run Code Online (Sandbox Code Playgroud)
请注意,由于文字整数被有效地解析为fromInteger <num>,fromInteger因此上述函数中的函数调用实际上不是必需的.我只是将它们包括在内以展示它的工作原理.
可用于检索值的其他常见类型类是:
Monad(使用return)Applicative(使用pure)Monoid(使用mempty)Read(使用read或其他任何其他功能)