Soru Operatörlerin aşırı yüklenmesi


Bir operatör tanımlamak istiyorum +-+) bunun içinde çalışır:

if a,b are Char    => a +-+ b = [a][b]
if a,b are Integer => a +-+ b = a+b

Denedim:

class Summable a where
    (+-+)       :: a -> a -> b

instance Summable Integer where
    a +-+ b     = a + b

instance Summable Char where
    a +-+ b     = [a] ++ [b]

ama hataları alıyorum:

Couldn't match type `b' with `Integer'....
Couldn't match type `b' with `[Char]' ....

Bunu yapmak mümkün mü? Nasıl?


18
2017-08-22 15:26


Menşei


Bunu not et [a] ++ [b] sadece [a,b]... - Ben Millwood


Cevaplar:


Sorun tip değişkendir. b düzeltilse bile örnekden belirlenemez. (Bunun gibi serbest bir değişkene sahip olmak, işlevin herhangi bir türü olan bir şeyi döndürmesini gerektirir, örn. undefined.)

Verebilir misin +-+ tip a -> a -> a? Eğer öyleyse, bunu yap. (Ama bu mümkün değil gibi görünüyor.)

Aksi halde kullanabilirsiniz işlevsel bağımlılıklarBöylece, örnek sonuç türünü belirtir, ya da aileleri yazınBöylece, örneklemin niteliklerinden biri sonuç türüdür.

İşlevsel bağımlılıklar için kod şöyle görünebilir:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}

class Summable a result | a -> result where
  (+-+) :: a -> a -> result

instance Summable Char String where
  a +-+ b = [a] ++ [b]

instance Summable Integer Integer where
  a +-+ b = a + b

Tip aileler için şöyle olurdu:

{-# LANGUAGE TypeFamilies #-}

class Summable a where
  type Result a
  (+-+) :: a -> a -> Result a

instance Summable Char where
  type Result Char = String
  a +-+ b = [a] ++ [b]

instance Summable Integer where
  type Result Integer = Integer
  a +-+ b = a + b

(Yaptığım çeşitli hataları düzeltmek için Vitus ve Vladimir Matveev'e teşekkür ederim! :))


25
2017-08-22 15:41