Sto scrivendo un'applicazione CRUD e ho un sacco di ricerche per chiave primaria (le chiavi primarie possono avere tipi diversi). Così ho definito seguente typeclass:Inferring Eq typeclass
{-# LANGUAGE MultiParamTypeClasses #-}
class Eq b => HasPK a b where
getPK :: a -> b
adesso posso scrivere:
import Data.Maybe
lookupPK :: HasPK a b => b -> [a] -> Maybe a
lookupPK s = listToMaybe . filter ((== s) . getPK)
Ora, quando voglio confrontare due cose con PK, voglio solo per confrontare le loro PK di. Quindi, sto cercando di definire questo:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
instance (HasPK a b) => Eq a where
(==) = (==) `on` getPK
Ma ora mi dà:
src/Utils.hs:61:10: Could not deduce (HasPK a b0) …
arising from the ambiguity check for an instance declaration
from the context (HasPK a b)
bound by an instance declaration: HasPK a b => Eq a
at /home/utdemir/workspace/.../Utils.hs:61:10-28
The type variable ‘b0’ is ambiguous
In the ambiguity check for: forall a b. HasPK a b => Eq a
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the instance declaration for ‘Eq a’
Compilation failed.
Qualcuno può spiegare questo errore a me? Sono sulla buona strada, o c'è un modo più sicuro per ottenere ciò che voglio?
Sì, dopo aver definito quell'istanza, ho ottenuto 'src/Utils.hs: 52: 20: Sovrapposizione di istanze per Eq Integer derivanti da un uso di '/ =' ... Istanze di corrispondenza: istanza Intero Eq - Definito nell'istanza 'integer-gmp: GHC.Integer.Type' (Eq b, HasPK a b) => Eq a'. Ma non mi aspettavo quell'errore poiché "Integer" non ha un'istanza "HasPk Integer b". Capirei l'errore se definisco sia Eq che HasPK, ma poiché non c'è 'HasPK Integer', non dovrebbe usare direttamente l'istanza' Eq'? – utdemir
@utdemir Il problema è: un 'esempio C a => Eq a' si applica ad ogni tipo, anche a quelli per i quali 'C a' è falso (!). Haskell si impegna a utilizzare questa istanza, e quando 'C a' è falso, si verificherà un errore, invece di tornare indietro e cercare altre istanze. Ciò avviene perché con il backtracking il problema diventa molto più difficile ei progettisti di Haskell si occupano del tempo di compilazione.GHC ha un'estensione 'OverlappingInstances' che rilassa questa restrizione, ma non la consiglierei. Le istanze sovrapposte sono le migliori da evitare, IMHO. – chi
Grazie, sono andato con la soluzione family type poiché sembra che l'estensione meno controversa sia quella. – utdemir