Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell: How can I define a type class for sets?

Total newbie here, struggling.

I'm trying to define a type class for sets. For this case it would only require the definition of 'exists'. 'exists' would take a set and function on a set item, and return a boolean. How can I define that in Haskell?

Is the following even in the right direction? So there is the type class definition and an implementation of set with list, for which 'exists' returns true for now..

-- Set.hs --

class Set a b where

  exists :: a -> (b -> Bool) -> Bool


-- ListSet.hs --

instance Set ListSet a where 

  exists a f = True

--

(result: Too many parameters for class `Set')

like image 256
tero Avatar asked Jul 16 '12 16:07

tero


People also ask

How do you assign a type in Haskell?

Haskell has three basic ways to declare a new type: The data declaration, which defines new data types. The type declaration for type synonyms, that is, alternative names for existing types. The newtype declaration, which defines new data types equivalent to existing ones.

How do you define a data type in Haskell?

The Data Keyword and Constructors In general, we define a new data type by using the data keyword, followed by the name of the type we're defining. The type has to begin with a capital letter to distinguish it from normal expression names. To start defining our type, we must provide a constructor.

What is Type Class Haskell?

What's a typeclass in Haskell? A typeclass defines a set of methods that is shared across multiple types. For a type to belong to a typeclass, it needs to implement the methods of that typeclass. These implementations are ad-hoc: methods can have different implementations for different types.

How do I check my type class in Haskell?

Within the Haskell language, there is no way to check whether a value has a certain type or whether a type is a member of a certain class. Haskell is not (quite) a proof verification system, so there's no way to prove, in Haskell code, that an instance declaration satisfies the specification of a class.


2 Answers

You can do it this way, with enough extensions. At the very least, you'll need multiple-parameter type classes. However, it will be very annoying to use: you'll need to specify explicit type signatures all over the place. One way to fix it is to introduce a functional dependency (using another extension):

class Set a b | a -> b where
    exists :: a -> (b -> Bool) -> Bool

This says that if you know the type of the set, you know the type of the elements, too. However, there's a simpler way that works without any extensions:

class Set f where
    exists :: f a -> (a -> Bool) -> Bool

Here, the type class ranges over higher-kinded types, which is a neat trick and hard to come up with on your own if you've never seen it before!

like image 95
Daniel Wagner Avatar answered Oct 23 '22 12:10

Daniel Wagner


Daniel Wagner already gave perfect answer on what you are trying to do. I just want to add a point about your error - Too many parameters for class 'Set'. This means that you didn't enable corresponding GHC extension - MultiParamTypeClasses. You can do it by specifying special kind of comment at the top of your source file:

{-# LANGUAGE MultiParamTypeClasses #-}
--
-- Your source code here
--

Then you should be able to compile your code.

Another Haskell feature mentioned in Daniel's answer also requires enabling certain extension, namely FunctionalDependencies (this is the weird .. | a -> b .. thing inside type class declaration). You can enable multiple extensions at the same time using comma, like this:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}

Carl's comment mentions another extension, TypeFamilies, which could also provide means for what you are trying to do (generic class of set types or other kind of collections). You can read about it here: http://www.haskell.org/haskellwiki/Type_families.

like image 45
Vladimir Matveev Avatar answered Oct 23 '22 13:10

Vladimir Matveev