Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell newtype, but keep old functions

Tags:

haskell

I want to define a type of "Ideal" which is a list but with some structure. Numeric prelude already defines instances of Ring for lists, but they're not using the definitions of addition and multiplication I want. So I think in this instance I should say

newtype Ideal a = Ideal [a]

This works fine, but now it gives me an error if I try to do, say take 5 $ Ideal [0..].

Is there a way that I can keep the functions I want and only override the definitions I explicitly override?

like image 878
Xodarap Avatar asked Aug 25 '11 02:08

Xodarap


People also ask

What does Newtype mean in Haskell?

One of the most common and useful Haskell features is newtype . newtype is an ordinary data type with the name and a constructor. However, you can define a data type as newtype instead of data only if it has exactly one constructor with exactly one field.

What is the difference between type and data in Haskell?

Type and data type refer to exactly the same concept. The Haskell keywords type and data are different, though: data allows you to introduce a new algebraic data type, while type just makes a type synonym. See the Haskell wiki for details.

How does deriving work in Haskell?

The second line, deriving (Eq, Show) , is called the deriving clause; it specifies that we want the compiler to automatically generate instances of the Eq and Show classes for our Pair type. The Haskell Report defines a handful of classes for which instances can be automatically generated.

What is instance Haskell?

An instance of a class is an individual object which belongs to that class. In Haskell, the class system is (roughly speaking) a way to group similar types. (This is the reason we call them "type classes"). An instance of a class is an individual type which belongs to that class.


2 Answers

If you're not too set on things being completely automatic, you could use the utility functions in the newtype package, e.g. something like over Ideal $ take 5.

Edit: Also, as an aside, it's not too hard to extend the functions from the newtype package to handle other cases. For example, I had these definitions lying around:

infixl 3 ./
(./) :: (Newtype n o) => (o -> t) -> (n -> t)
(./) fx = fx . unpack

liftN f x = pack $ f ./ x
liftN2 f x y = pack $ f ./ x ./ y
liftN3 f x y z = pack $ f ./ x ./ y ./ z

Not actually the best design for such combinators, I suspect, but you get the idea.

like image 94
C. A. McCann Avatar answered Oct 24 '22 03:10

C. A. McCann


For plain functions, no. You'll have to provide your own definitions.

However, for functions that belong to a type class, you can use the GeneralizedNewtypeDeriving extension to expose the type classes you want from the underlying type of a newtype.

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype MyState a = MyState (State Int a)
    deriving (Monad)
like image 44
hammar Avatar answered Oct 24 '22 02:10

hammar