geçen gün vermeden bir fonksiyonun birden çok sürümünü kullanarak bir matris içinde sayıların bir demet toplamak için küçük bir program yazdım i Bu işlev sonra LeftUp
ve Right
polimorfizmi - bir köşede başlayan <code>data Matrix = Matrix [[Int]]</code> - - <code>Corner</code> ve Yol'u takip - <code>[Direction]</code> tüm farklı isimler o
turnLUR :: Transformable a => (Corner, Direction) -> a -> a
kullanma - üç tip bir sınıf sonra Transformable
ı, belirli bir köşe ve yön döner bir dönüştürme işlevi üreten bir fonksiyon, var örneğidir "Hasat" matris içinde tüm sayılar için:
harvest :: Matrix → [(Corner,Direction)] → [Int]
harvest _ [] = []
harvest (Matrix []) _ = []
harvest as (cd:csds) = b ++ harvest (Matrix bs) csds' --cd = (Corner,Direction)
where f1 = turnLUR cd -- Matrix -> Matrix
f2 = turnLUR cd -- Corner -> Corner
f3 = turnLUR cd -- Direction -> Direction
Matrix (b:bs) = f1 as -- b = first line of [[Int]]
fcfd (c,d) = (f2 c,f3 d)
csds' = map fcfd csds
Şimdi
f1
,
f2
ve
f3
yerine bir fonksiyonu kullanımına yazmak zorunda yapmak neden benim sorum
f
üç kez (! Zihnimde KURU tutarak) - her üç tip
Corners
,
Directions
ve
Matrix
,
class Transformable
'un örnekleridir.
Bu kodu "aynı" işlevin üç sürümünü yapmaksızın nasıl yazarım?
Monomorfizma kısıtlamasının yalnızca anlamsız stilde yazılan işlevleri (işlevler olmayan değerlerin yanı sıra) etkilediğini unutmayın, bu nedenle, 'f' açık parametreleri kullanarak tanımladığınızda, kısıtlamadan etkilenmezsiniz. bir tür imza vermeyin. – sepp2k
, bu nedenle, tür imzası için bir işlev belirtilmekte olan 'f :: Transformable a => a -> a' tip imzasıdır; ve o olmadan derleyici 'f'' Matrix -> Matrix' türünde ilk kullanım olduğu için çıkar. Bunu açıklamak için çok teşekkür ederim. Özellikle imzanın bu monomorfizm kısıtlamasını çözebileceğini bilmiyordum. – epsilonhalbe