Starting point:
fn :: [a] -> Int fn = (2 *) . length
Suppose we want to limit the return value, then we could write:
fn list = (2 * length list) :: Int
How about limiting just an argument? Easily.
fn list = 2 * length (list :: [Char])
While this works, it would be preferable to have the labels at the top collected and not scattered around the body of the function.
This is the closest I can think of:
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 would like a cleaner solution. Something that reports that my intention is a partial restriction. Something like this, for example:
fn :: [Char] -> a fn = (2 *) . length
Or maybe:
fn :: [Char] -> _ fn = (2 *) . length
Is it possible?
Edit for further clarification:
@GaneshSittampalam Made an important point in the comments below. I am looking for "a house halfway between a type signature and generally should give an exact one." So, I'm not looking for an answer based on TypeClass, I just want the GHC to fill in the blanks for the undefined (or not completely limited) types of my function.
Edit in response to @WillNess
Yes, something like this ...
fn list = 2 * length list where _ = list :: [Char]
... may work, but only for arguments, and only if the function is not point-wise. Is there a way to apply this method to centerless functions or return values?
Edit in response to @Rhymoid
I got inspiration and played with @Rhymoid 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 limits the signature to fn and does not pollute any namespace.
Usually we will have only one of the lines asTypeOf , I just added a few to demonstrate how powerful this approach is.
This is a bit more awkward than what I would like, but I think it's pretty neat, we can do this even without special syntactic support from the language.
@Rhymoid, if you like it, add it to your answer. :)