によると，

```nub              :: (Eq a) => [a] -> [a]
nub []           =  []
nub (x:xs)       =  x : nub (filter (y -> not (x == y)) xs)
```

なので，実はnubはO(n^2). Eq だけ，だから仕方ないのかもしれないが．

しかし，

```nub :: (Ord a) => [a] -> [a]
```

にすれば，O(n log n) にできる．Setのmember, insertは log n であることを利用する．

```import Data.Set (empty, member, insert)
nub' :: (Ord a) => [a] -> [a]
nub' l = nub'' l empty
where nub'' [] _         = []
nub'' (x:xs) s
| x `member` s = nub'' xs s
| otherwise    = x : nub'' xs (x `insert` s)
```

O(n^2) と O(n log n) では大違いです． cf. sort

ところで，ソース

を見てみたら，#ifdef USE_REPORT_PRELUDE なんて文がある．どうやらnubの実装には2種類あるみたい．

しかし，自分のghcはどちらを使っているのか？

```nub                     :: (Eq a) => [a] -> [a]
#ifdef USE_REPORT_PRELUDE
nub                     =  nubBy (==)
#else
-- stolen from HBC
nub l                   = nub' l []             -- '
where
nub' [] _           = []                    -- '
nub' (x:xs) ls                              -- '
| x `elem` ls   = nub' xs ls            -- '
| otherwise     = x : nub' xs (x:ls)    -- '
#endif
-- | The 'nubBy' function behaves just like 'nub', except it uses a
-- function.
nubBy                   :: (a -> a -> Bool) -> [a] -> [a]
#ifdef USE_REPORT_PRELUDE
nubBy eq []             =  []
nubBy eq (x:xs)         =  x : nubBy eq (filter ( y -> not (eq x y)) xs)
#else
nubBy eq l              = nubBy' l []
where
nubBy' [] _         = []
nubBy' (y:ys) xs
| elem_by eq y xs = nubBy' ys xs
| otherwise       = y : nubBy' ys (y:xs)
-- Not exported:
-- Note that we keep the call to `eq` with arguments in the
-- same order as in the reference implementation
-- 'xs' is the list of things we've seen so far,
-- 'y' is the potential new element
elem_by :: (a -> a -> Bool) -> a -> [a] -> Bool
elem_by _  _ []         =  False
elem_by eq y (x:xs)     =  y `eq` x || elem_by eq y xs
#endif
```

# log は定数だから， O(n log n) => O(n)．やったリニアだ．