Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define function signatures partially in Haskell?

Tags:

haskell

Starting point:

fn :: [a] -> Int fn = (2 *) . length 

Let's say we only want to constrain the return value, then we could write:

fn list = (2 * length list) :: Int 

How about restricting only the argument? Easy.

fn list = 2 * length (list :: [Char]) 

While this works, it would be preferable to have the signatures at the top collected and not scattered around the function body.

This is the closest I could come to this:

fnSig = undefined :: [Char] -> a fn | False = fnSig    | True  = (* 2) . length 

Based on http://okmij.org/ftp/Haskell/partial-signatures.lhs via http://okmij.org/ftp/Haskell/types.html#partial-sigs

However, I'd like a cleaner solution. Something that communicates better that my intent is partial restriction. Something like this, for example:

fn :: [Char] -> a fn = (2 *) . length 

Or maybe:

fn :: [Char] -> _ fn = (2 *) . length 

Is this possible?

Edit for further clarification:

@GaneshSittampalam Made an important point in a comment below. I am looking for "a half-way house between no type signature at all and having to give a precise one". So, I am not looking for a TypeClass-based answer, I just want GHC to fill in the blanks for the unspecified (or not fully restricted) types of my function.

Edit in response to @WillNess

Yes, something like this...

fn list = 2 * length list   where     _ = list :: [Char] 

...could work, but only for arguments, and only if the function is not point-free. Is there a way to apply this technique to point-free functions or return values?

Edit in response to @Rhymoid

I got inspired, and played around with @Rhymoid's idea, and came up with this:

fn = (2 *) . length   where     _ = fn `asTypeOf` (undefined :: [Char] -> a)     _ = fn `asTypeOf` (undefined :: a -> Int)     _ = fn `asTypeOf` (undefined :: a -> b)     _ = fn `asTypeOf` (undefined :: a) 

This approach also restricts fn's type signature, and doesn't pollute any namespace.

Ordinarily we would only have one of the asTypeOf lines, I just added multiple to showcase how powerful this approach is.

It is a little more clumsy than how I would like it, but I guess it is pretty neat we can do this even without specific syntactic support from the language.

@Rhymoid, if you like it too, please add it to your answer. :)

like image 475
Wizek Avatar asked Feb 09 '14 11:02

Wizek


People also ask

What are type signatures in Haskell?

From HaskellWiki. A type signature is a line like. inc :: Num a => a -> a. that tells, what is the type of a variable. In the example inc is the variable, Num a => is the context and a -> a is its type, namely a function type with the kind * -> * .

WHAT IS function's signature?

A function signature (or type signature, or method signature) defines input and output of functions or methods. A signature can include: parameters and their types. a return value and type. exceptions that might be thrown or passed back.

What does () mean in Haskell?

() is very often used as the result of something that has no interesting result. For example, an IO action that is supposed to perform some I/O and terminate without producing a result will typically have type IO () .


1 Answers

Sorry for the self-promotion, but exactly this feature is the topic of a recent paper by Ph.D. student Thomas Winant, myself, Frank Piessens and Tom Schrijvers, very recently presented by Thomas at the PADL 2014 symposium. See here for the full paper. It is a feature that is already present in some other languages, but the interaction with features like Haskell GADTs made it interesting enough to work out the details.

Thomas is working on an implementation for GHC. It has further improved since the writing of the paper, but implementing the "wildcard constraint" in GHC is technically a bit harder than we expected. We expect to be able to work further on it and contact the GHC developers to get it adopted, but whether or not this happens may depend on how much people would like to have the feature in Haskell...

Update 14-4-2015: After a lot of work by Thomas and input from SPJ and other GHC people, partial type signatures have been released in GHC 7.10. Thomas Winant wrote an introductory blog post about how you can use them.

like image 110
Dominique Devriese Avatar answered Sep 27 '22 22:09

Dominique Devriese