我想列印函式的回傳型別(在本例中為“整數”):
{-# 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
相反,它正在列印“<unmatched case>”。這對我來說似乎很奇怪,因為回傳型別 ofinc::Integer->Integer顯然是Integer.
是否可以匹配這樣的函式呼叫的回傳值型別的實體?
(這個例子很愚蠢,它是一個基于更復雜的東西的玩具片段。我只是想理解為什么它與更具體的實體不匹配。)
uj5u.com熱心網友回復:
{-# 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 (&&) ===> "布爾"
-- getReturnType ( ) ===> 錯誤 - 未解決的多載型別: (Num a, hasReturnType a) => [Char]
inc :: Integer -> Integer
inc = undefined -- doesn't need a binding
-- getReturnType inc ===> "整數"
uj5u.com熱心網友回復:
比較您的實體:
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 提交給實體的確切點就無關緊要了。)
uj5u.com熱心網友回復:
你的例子不正確。唯一有效的代碼路徑是通過默認情況。它使型別類實體決議短路。
一個滿足您期望的固定示例是:
{-# 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/478650.html
標籤:哈斯克尔
上一篇:無法在React中使用NPM包
