比方說,我們有:爲什麼haskell強制總是鍵入泛型?
data Data a b c = Build (a,b,c) deriving Show
foo :: Data a b c -> Data a b c
foo d = d
main = print $ foo $ Build (1, 1, "a")
有什麼辦法避免書面方式a b c
每次使用的數據類型?
使用類型,是這樣的:
foo :: Data -> Data
foo d = d
比方說,我們有:爲什麼haskell強制總是鍵入泛型?
data Data a b c = Build (a,b,c) deriving Show
foo :: Data a b c -> Data a b c
foo d = d
main = print $ foo $ Build (1, 1, "a")
有什麼辦法避免書面方式a b c
每次使用的數據類型?
使用類型,是這樣的:
foo :: Data -> Data
foo d = d
是的,肯定的:
foo :: d ~ Data a b c => d -> d
因爲Data
不是一個類型,但類型構造。如果你喜歡一個函數,它需要3種類型並返回一個新類型。類型構造也可以種其他類型的構造函數作爲參數,例如
data D d a= D (d a a a)
然後我就可以用你的Data
(無參數)D Data a
......
data Data a b c = Build (a,b,c) deriving Show
type D a t a' = Data a t a'
foo :: D a t a' -> D a t a'
foo d = d
別名是有趣的,但是這不打算作爲一個嚴肅的答案。
編輯:嚴重的版本,如果你知道一個共同的單態類型,那麼別名成材:
type AppData = Data AppState AppValue AppResult
foo :: AppData -> AppData
...
優秀的答案。 –
這是非常有創造力,偉大的工作! – AJFarmar
您可以在type
代名詞包裹起來的多態類型。
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}
type d ~> d' = forall a b c. d a b c -> d' a b c
foo :: Data ~> Data
foo d = d
雖然寫出類型變量可能更簡單。
實際上你根本沒有寫*類型簽名。如果你忽略它們,Haskell會爲你派生它們。 –
@WillemVanOnsem,我知道這件事,除此之外別說。將編輯 – Netwave