class 函数的实例选择 return 值
class instance selection of a function return value
我想打印 return 类型的函数(在本例中为“整数”):
{-# LANGUAGE FlexibleInstances #-}
import Data.Default
class HasReturnType a where
getReturnType :: a -> String
instance Default a => HasReturnType (a->b) where
getReturnType f = getReturnType (f def)
instance HasReturnType Integer where
getReturnType _ = "Integer"
instance {-# Overlappable #-} HasReturnType a where
getReturnType _ = "<unmatched case>"
inc :: Integer -> Integer
inc = (+1)
main = do
putStrLn $ getReturnType inc
而是打印“”。这对我来说似乎很奇怪,因为 inc::Integer->Integer
的 return 类型显然是 Integer
.
是否可以匹配像这样的函数调用的 return 值类型的实例?
(这个例子很傻,它是一个基于更复杂事物的玩具片段。我只是想了解为什么它与更具体的实例不匹配。)
你的例子不正确。
唯一有效的代码路径是通过默认情况。它使类型类实例解析短路。
一个 fill 做你期望的固定例子是:
{-# Language FlexibleInstances #-}
import Data.Typeable
class Default a where
def :: a
instance Default Integer where
def = 1
class HasReturnType a where
getReturnType :: a -> String
instance (Default a, Typeable b) => HasReturnType (a->b) where
getReturnType f = show . typeOf $ f def
instance {-# Overlappable #-} HasReturnType a where
getReturnType _ = "<unmatched case>"
instance HasReturnType Integer where
getReturnType _ = "Integer"
inc :: Integer -> Integer
inc = (+1)
main = do
putStrLn $ getReturnType inc
{-# LANGUAGE FlexibleInstances, ScopedTypeVariables #-}
module FuncReturn where
class HasReturnType a where
getReturnType :: a -> String
instance HasReturnType b => HasReturnType (a -> b) where
getReturnType f = getReturnType $ f undefined
-- instance HasReturnType b => HasReturnType (a -> b) where
-- getReturnType f = getReturnType (undefined :: b)
-- needs ScopedTypeVariables ^^^^
instance HasReturnType Integer where
getReturnType _ = "Integer"
instance HasReturnType Int where
getReturnType _ = "Int"
instance HasReturnType String where
getReturnType _ = "String"
instance HasReturnType Bool where
getReturnType _ = "Bool"
instance {-# OVERLAPPABLE #-} HasReturnType ab where
getReturnType _ = "<unmatched case>"
-- getReturnType 长度===> "Int"
-- getReturnType (&&) ===> "Bool"
-- getReturnType (+) ===> 错误 - 未解析的重载类型:(Num a, hasReturnType a) => [Char]
inc :: Integer -> Integer
inc = undefined -- doesn't need a binding
-- getReturnType inc ===> "整数"
比较您的实例:
instance (Default a) => HasReturnType (a->b) where
getReturnType f = getReturnType (f def)
使用此变体(差异已加下划线):
instance (Default a, HasReturnType b) => HasReturnType (a->b) where
---------------
getReturnType f = getReturnType (f def)
在前一个实例中,调用getReturnType (f def)
需要解决约束HasReturnType b
。 GHC 立即尝试解决这个问题,当 b
仍然未知时,唯一适用的实例是通用的“不匹配的案例”,因此它致力于解决这个问题。
相比之下,后一个实例我们可以使用更大的上下文来解决约束:这使得 GHC 选择那个,有效地延迟了从这个调用点到 main
中的实例的选择。因此有效。
经验法则:GHC 尝试在每个调用点解决约束。如果此时您不想提交到特定实例,则需要在上下文中提供约束,以便延迟选择。 (当然,如果我们不使用重叠实例,GHC 提交实例的确切点是无关紧要的。)
我想打印 return 类型的函数(在本例中为“整数”):
{-# LANGUAGE FlexibleInstances #-}
import Data.Default
class HasReturnType a where
getReturnType :: a -> String
instance Default a => HasReturnType (a->b) where
getReturnType f = getReturnType (f def)
instance HasReturnType Integer where
getReturnType _ = "Integer"
instance {-# Overlappable #-} HasReturnType a where
getReturnType _ = "<unmatched case>"
inc :: Integer -> Integer
inc = (+1)
main = do
putStrLn $ getReturnType inc
而是打印“inc::Integer->Integer
的 return 类型显然是 Integer
.
是否可以匹配像这样的函数调用的 return 值类型的实例?
(这个例子很傻,它是一个基于更复杂事物的玩具片段。我只是想了解为什么它与更具体的实例不匹配。)
你的例子不正确。 唯一有效的代码路径是通过默认情况。它使类型类实例解析短路。
一个 fill 做你期望的固定例子是:
{-# Language FlexibleInstances #-}
import Data.Typeable
class Default a where
def :: a
instance Default Integer where
def = 1
class HasReturnType a where
getReturnType :: a -> String
instance (Default a, Typeable b) => HasReturnType (a->b) where
getReturnType f = show . typeOf $ f def
instance {-# Overlappable #-} HasReturnType a where
getReturnType _ = "<unmatched case>"
instance HasReturnType Integer where
getReturnType _ = "Integer"
inc :: Integer -> Integer
inc = (+1)
main = do
putStrLn $ getReturnType inc
{-# LANGUAGE FlexibleInstances, ScopedTypeVariables #-}
module FuncReturn where
class HasReturnType a where
getReturnType :: a -> String
instance HasReturnType b => HasReturnType (a -> b) where
getReturnType f = getReturnType $ f undefined
-- instance HasReturnType b => HasReturnType (a -> b) where
-- getReturnType f = getReturnType (undefined :: b)
-- needs ScopedTypeVariables ^^^^
instance HasReturnType Integer where
getReturnType _ = "Integer"
instance HasReturnType Int where
getReturnType _ = "Int"
instance HasReturnType String where
getReturnType _ = "String"
instance HasReturnType Bool where
getReturnType _ = "Bool"
instance {-# OVERLAPPABLE #-} HasReturnType ab where
getReturnType _ = "<unmatched case>"
-- getReturnType 长度===> "Int"
-- getReturnType (&&) ===> "Bool"
-- getReturnType (+) ===> 错误 - 未解析的重载类型:(Num a, hasReturnType a) => [Char]
inc :: Integer -> Integer
inc = undefined -- doesn't need a binding
-- getReturnType inc ===> "整数"
比较您的实例:
instance (Default a) => HasReturnType (a->b) where
getReturnType f = getReturnType (f def)
使用此变体(差异已加下划线):
instance (Default a, HasReturnType b) => HasReturnType (a->b) where
---------------
getReturnType f = getReturnType (f def)
在前一个实例中,调用getReturnType (f def)
需要解决约束HasReturnType b
。 GHC 立即尝试解决这个问题,当 b
仍然未知时,唯一适用的实例是通用的“不匹配的案例”,因此它致力于解决这个问题。
相比之下,后一个实例我们可以使用更大的上下文来解决约束:这使得 GHC 选择那个,有效地延迟了从这个调用点到 main
中的实例的选择。因此有效。
经验法则:GHC 尝试在每个调用点解决约束。如果此时您不想提交到特定实例,则需要在上下文中提供约束,以便延迟选择。 (当然,如果我们不使用重叠实例,GHC 提交实例的确切点是无关紧要的。)