2012-06-29 14 views
6

Próbuję zaimplementować fmapę Functor na Data.Map.Map, ale pojawia się błąd. Jestem pewien, że nie muszę konwertować mapy na i z listy, aby to działało, ale jest to najlepsze, co do tej pory wymyśliłem."Brak instancji dla (Ord k)" podczas implementacji Functor over Data.Map.Map

class Functor' f where 
    fmap' :: (a -> b) -> f a -> f b 

instance Functor' (Map.Map k) where 
    fmap' f m 
     | Map.null m = Map.empty 
     | otherwise = let x:xs = Map.toList m 
          mtail = Map.fromList xs 
          a = fst x 
          b = snd x 
         in Map.insert a (f b) (fmap f mtail) 

Błąd:

No instance for (Ord k) 
    arising from a use of `Map.fromList' 
In the expression: Map.fromList xs 
In an equation for `mtail': mtail = Map.fromList xs 
In the expression: 
    let 
    x : xs = Map.toList m 
    mtail = Map.fromList xs 
    a = fst x 
    .... 
    in Map.insert a (f b) (fmap f mtail) 

Jakieś pomysły?

+3

Po prostu wpisz 'Ord' w kontekście:' instance Ord k => Functor '(Map.Map k) where'. – JJJ

+0

Dobrze, dziękuję! Czy jest lepszy sposób niż konwersja do iz listy? – pyrospade

+0

Tak, istnieje lepszy sposób na napisanie 'fmap' dla' Functor (Map k) 'bez używania list i ograniczenia' Ord k' w ogóle. Tak działa 'Data.Map.map' (==' fmap' dla 'Map k'): http://www.haskell.org/ghc/docs/latest/html/libraries/containers-0.4.2.1/ src/Data-Map.html # mapa. Ale jeśli chcesz użyć 'toList' /' fromList', to coś jak 'fmap 'f = Map.fromList. mapa (drugi f). Map.toList' byłoby prostsze ('second' pochodzi z' Control.Arrow'). – JJJ

Odpowiedz

2

Błąd spowodowany jest nieprzypisaniem predykatu Ord do zmiennej typu k. Po prostu zrób to:

instance Ord k => Functor' (Map.Map k) where