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?
@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.
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?
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. :)
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 * -> * .
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.
() 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 () .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With