我已經宣告了以下資料型別
data Poly a = Poly [a]
還有一個類:
class Polynom p where
substitute :: p a -> a -> a
compose :: p a -> p a -> p a
我可以使資料型別成為類的實體:
instance Polynom Poly where
substitute = ...
compose = ...
我也希望 aRatio是Poly同一個類的實體;我嘗試了很多語法和語言擴展,但沒有一個有效;像:
instance Polynom (Ratio . Poly) where ...
-- error: cannot use (.) there
instance Poly p => Polynom (Ratio (p _)) where ...
-- error: no wildcards allowed
type X a = Ratio (Poly x)
instance Polynom X where ...
-- error: X needs another param
instance Polynom (* -> Ratio (Poly *)) where ...
-- error: wrong kind
我的目標是能夠擁有substitute和compose作業Ratio (Poly *);例如:
rf1 = Poly [1,2,3] % Poly [4,5,6] :: Ratio (Poly Int)
rf2 = Poly [0,1] % Poly [1,0] :: Ratio (Poly Int)
rf = rf1 `compose` rf2 :: Ratio (Poly Int)
result = substitute rf 10 :: Int
這在 Haskell 中甚至可能嗎?如果是這樣,我在這里缺少什么語法或語言擴展?
更新
我使用 TypeFamilies 解決了這個問題;正如@leftaroundabout 所建議的那樣。作業類實體看起來像這樣*:
instance Integral a => Polynom (Ratio (Poly a)) where
type Domain (Ratio (Poly a)) = Ratio a
substitute (n :% d) x = substitute ((%1) <$> n) x
/ substitute ((%1) <$> d) x
compose (n :% d) = substitute ((pure <$> n) % (pure <$> d))
*(實際上我也更改了不好的名字;但將它們保留在這里以避免混淆)
uj5u.com熱心網友回復:
首先......如果你想要那個實體,那么這個類的名字是錯誤的;兩個多項式的商不是多項式。
其次,您甚至不能像類一樣擁有實際多項式的實體,您至少需要Num約束。
class Polynom p where
substitute :: Num a => p a -> a -> a
compose :: Num a => p a -> p a -> p a
也就是說,就 Haskell 而言,這里沒有太多阻礙。
.顯然不能在型別級別上使用,但這Compose是一種等效的東西。
data Compose f g a = Compose { getCompose :: f (g a) }
這意味著用于組合函子,它Ratio不是?,但是我認為沒有理由不使用它來組合任意的Type -> Type東西。
instance Polynom (Compose Ratio Poly) where
substitute (r%d) = substitute r / substitute d
...此時您會發現Num約束還不夠。不過Fractional,在Polynomial課堂上要求會有點傻。
我建議你以完全不同的方式處理它。你可以使用一個類
{-# LANGUAGE TypeFamilies #-}
import Data.Kind (Type)
class Endofunction f where
type Domain f :: Type
evaluate :: f -> Domain f -> Domain f
compose :: f -> f -> f
然后實體是
instance Num a => Endofunction (Poly a) where
type Domain (Poly a) = a
...
而且,現在不需要Compose,
instance Fractional a => Endofunction (Ratio (Poly a)) where
type Domain (Ratio (Poly a)) = a
...
?我懷疑您實際上可以將它視為介于兩個類別之間的函子,但它肯定不是Hask 內函子。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/326052.html
標籤:哈斯克尔
