выглядит хорошо для меня (для «бесполезных упражнений», как вы выразились); Одно: ни одна из ваших подписей не требует специализирования как Integer, все, что поддерживает равенство (Eq), будет работать, при этом powerset дополнительно требует числовое значение (опять же, не обязательно Integer):
noReps :: Eq a => Set a -> Set a
inclusion :: Eq a => Set a -> Set a -> Bool
identical :: Eq a => Set a -> Set a -> Bool
setmember :: Eq a => Set a -> Set (Set a) -> Bool
addsets :: Eq a => Set a -> Set (Set a) -> Set (Set a)
addelem :: Eq a => a -> Set (Set a) -> Set (Set a)
powerset :: (Eq a, Num a) => a -> Set (Set a)
Все эти подписи будут работать, абсолютно ничего не меняя в самих функциях.
(РЕДАКТИРОВАТЬ: обычно хорошей идеей является сделать ваши подписи как можно более универсальными и полиморфными - это не только позволит повторно использовать код, но и ограничит то, что ваши функции могут делать со своими аргументами - в данном случае, сигнатура позволяет применять ТОЛЬКО оператор == - вы снижаете риск ошибок / непреднамеренных эффектов).
Конечно, использование списков сделает код простым, но медленным - для реального кода вы бы использовали сбалансированные деревья для представления наборов - более сложным, но быстрым; фактически, именно так реализован собственный тип Set в Haskell.