glguy / tries

BSD 3-Clause "New" or "Revised" License
11 stars 8 forks source link

Clarify that this does not work for nested data types #21

Closed sgraf812 closed 2 years ago

sgraf812 commented 2 years ago

I'm currently following Generalizing Generalized Tries (there's also a slightly different publicly available version here) which describes derivation of tries for nested data structures such as Perfect below (note the nested recursion for Fork a) as quite challenging. Out of curiosity, I tried the following code

{-# LANGUAGE DeriveGeneric #-}

import Data.GenericTrie
import GHC.Generics

data Fork a = Fork a a
  deriving Generic
data Perfect a = Zero a | Succ (Perfect (Fork a))
  deriving Generic

foo :: Trie (Perfect Int) Int
foo = empty

And it errors out with

    • No instance for (TrieKey (Perfect Int))
        arising from a use of ‘empty’
    • In the expression: empty :: Trie (Perfect Int) Int
      In an equation for ‘foo’: foo = empty :: Trie (Perfect Int) Int

Which I think is reasonable if it was properly documented.

sgraf812 commented 2 years ago

Ah, nevermind. I obviously forgot the instance TrieKey declarations. If I add

instance TrieKey a => TrieKey (Fork a) where
instance TrieKey a => TrieKey (Perfect a) where

bar :: Trie (Perfect Int) Int
bar = singleton (Succ (Succ (Zero (Fork (Fork 1 2) (Fork 3 4))))) 42

it works. But empty :: Trie (Perfect a) Int will only work with a TrieKey a constraint. Anyway, will close this again.