Test a function's type - haskell

I'm new to haskell. I read this answer and I would also like to test the type of my functions, if there is a way to do it.
Here is an example : test.hs
module Test where
import Test.HUnit
test1 = TestCase (assertEqual "test1" 3 (length [1,2,3]))
tests = TestList [test1]
main :: IO Counts
main = runTestTT tests
I'm running the code with runghc test.hs and I get:
Cases: 1 Tried: 1 Errors: 0 Failures: 0
Now, how can I test the type for the length function ?
I have already tried adding a second test test2 = TestCase (assertEqual "test2" "length :: Foldable t => t a -> Int" :type length), but I get this error test.hs:5:77: parse error on input 'type'.
Thanks

Writing a test for a type is almost definitely not what you want. Since Haskell is statically typed, the compiler automatically checks types for you when you compile, with no need to run any code or tests. If length did not have a compatible type, you would get a type error if you tried to load the code at all.
:type is a special command from ghci, not actual Haskell syntax. You can't use it directly in a normal program. There are ways to get a value representing a type but they're somewhat complicated and, again, almost definitely not what you need.

Although I agree with the other answer that the question smells, I think it is worth giving a direct answer anyway. You could put a type assertion in your test suite like this:
module Test where
check_type_of_length :: Foldable t => t a -> Int
check_type_of_length = length
If length can not be given the type you requested, the module will not compile. However, this is not a perfect test: if the type of length is actually more polymorphic than the type you demand, this will still "pass"; thus, for example, the following module still compiles, even though undefined does not have exactly the type Foldable t => t a -> Int.
module Test where
check_type_of_length :: Foldable t => t a -> Int
check_type_of_length = undefined
We can make the test a bit more precise if you want to check a monomorphic type. The idea is to use Typeable, as suggested by #dfeuer. That would look like this:
module Test where
import Data.Typeable
test_type_of_not :: Bool
test_type_of_not = typeOf not == typeOf (undefined :: Bool -> Bool)
If not has the monomorphic type Bool -> Bool, then test_type_of_not will be True; if it has a different monomorphic type, it will be False; and if not suddenly becomes polymorphic, the module will fail to compile with an ambiguity error.
I do not know an analogous way to test that a polymorphic type does not become more polymorphic; you could perhaps do something nasty like running a short bash script that does
echo :t length | ghci
and checking its output, or something more direct with the GHC API. However, an approach like this is likely to be very fragile.

Related

Getting/returning the type of a function

Is there any way to get and return the type of a function in Haskell?
Suppose that I have this kind of function:
foo :: Int -> Int -> String
foo a b = (show a ++ show b ++ "hello")
From the code above, what I actually want is to get this kind of tuple as a return value of function:
> getTypeTuple foo
(Int, Int, String)
As far as I know, the type itself cannot be treated as a part of expressions, so I guess it wouldn't be possible to have this kind of feature at the runtime in Haskell. (Static type!!)
Then will there be any similar alternative, or preprocessor feature in Haskell?
Edit: I think what I really want is the Haskell implementation of :t command in GHCi.
You can use Template Haskell to do your metaprogramming, and that allows you to get the type of a function. See this question for how to get the type.

GHCI can't infer Eq class at compile time, but does fine at runtime?

Sorry for the confusing title. I am writing a parser combinator library in Haskell for fun. Here are all (I think!) the relevant type annotations and definitions:
data Parser a = Parser (State -> Reply a)
parse :: Parser a -> [Char] -> Either ParseError a
nil :: Parser [a]
nil = Parser $ \state -> Ok [] state
Basically, the parse function applies the function that a Parser wraps around to the current state, and if the parse is successful, wraps the result in an Either. The nil parser takes a state and returns a successful parse of the empty list. So we should have,
parse nil "dog" == Right []
In fact, if I just load the module where all these live, then it compiles and this evaluates to True.
I'm actually trying to run some QuickCheck tests on the library, though, so I wrote this:
import Parsimony
import Test.QuickCheck
prop_nil :: [Char] -> Bool
prop_nil xs = parse nil xs == Right []
This fails to compile! It throws the following error:
No instance for (Eq a0) arising from a use of `=='
The type variable `a0' is ambiguous
At this point I am mostly just confused why an expression could work fine when evaluated, but fail to compile in a parametrized version.
Since nil is polymorphic and Right [] is also polymorphic GHC has an expression of type Bool, but with some unbound type variable in the middle. GHC keels over and dies since it doesn't know what concrete type to use. GHCi for better or worse, will infer [()] or something like that because of its defaulting rules. This is one of ghci's weird quirks, it will automagically default type variables.
To fix this, simply for force the binding of a manually
-- It's important that whatever you force it to actually is comparable
-- eg there should be an instance like
instance Eq ParseError where
-- Otherwise you're kinda stuck.
prop_nil xs = parse nil xs == (Right xs :: Either ParseError String)
PS I like the name Parsimony for a parser library, good luck!
The problem is that the type of nil is Parser [a]. So parse nil xs is of type Either ParseError [a]. Right [] is most generally of type Either l [a]; comparing it to parse nil xs forces the l to be ParseError, but the type in the list is still completely unconstrained. Without any more context it remains fully polymorphic; that a isn't necessarily a member of the Eq type class and even if it is there's no way to know which instance to use for the implementation of ==, and so it isn't valid to invoke == on those two terms.
In a realistic program, you'd likely be saved from this by the fact that you'd use the result for something, which would force that particular occurrence to be consistent with whatever you use it for. That would probably be some concrete type which has an implementation of Eq.
When you talk about loading the module, I presume you mean in the GHCI interpreter. GHCI adds some additional defaulting rules. In particular it will tend to default unconstrained type variables (which aren't the type of a top level function) to (), so that it doesn't have to complain about ambiguous type variables quite so often.
An interactive session in GHCi tends to encounter ambiguous type variable far more often than realistic modules compiled in full, because it has to compile small snippets mostly independently. GHCi has extended defaulting rules to make those work a lot more often (though it often only delays the error to the next reference when the user was expecting a different type, and the difference between GHCi and GHC often causes confusion).
Test snippets can suffer from a similar problem. If you're testing polymorphic functions you often don't constrain some of the types sufficiently for type inference to work, as you would in real purposeful usage of the function. But without the extended defaulting rules of GHCi, this problem manifests as an actual ambiguous type error at the location of the problem, rather than masking it by arbitrarily picking a type.
To fix this, you just need to add a type annotation to fix the type of the list. Either declare the full type of parse nil xs or Right [], just declare the type of the empty list literal on the right hand side. Sometihng like this should do the trick:
prop_nil :: [Char] -> Bool
prop_nil xs = parse nil xs == Right ([] :: [Int])
Another way would be to avoid the Eq constraint in the first place:
prop_nil xs = either (const False) null (parse nil xs)
or, more explicit
prop_nil xs = case parse nil xs of
Right [] -> True
_ -> False

What type is chosen for a polymorphic expression when printed?

What is the type of return "abc" when printed in ghci?
The point of the question is that it's polymorphic in the monad:
ghci> :t return "abc"
return "abc" :: (Monad m) => m [Char]
and what gets printed depends on which monad is chosen:
ghci> return "abc" :: Maybe String
Just "abc"
ghci> return "abc" :: [] String
["abc"]
but here's what's actually printed:
ghci> return "abc"
"abc"
When you type an expression expr into GHCi, the following things happen:
The expression is type-checked. If there is an error, GHCi tells you the error and gives up.
Otherwise, say expr is found to have type t; GHC tries to match t against IO a.
If it succeeds, then it executes something like it <- expr, then if a is an instance of Show and is not (), it executes print it.
If it fails, and t itself is an instance of Show, GHCi does something like let it = expr and then print it.
Otherwise, it complains.
Essentially, you need a way at the GHCi prompt both of running IO actions and getting at the values they return, and of playing around with pure values and seeing what you get. That's why GHCi behaves the way it does: if it seems like you're using an IO action, GHCi will do it, and then if that action has a result that can be shown and is interesting (i.e. not ()) then it shows the result to you. If it can't show the result to you, then it's no big deal, because you probably just wanted to run the IO action anyway; if you wanted the result you would have named it with <-. On the other hand, if it seems like your expression is not an IO action, GHCi calculates it and shows it to you, and if it can't be shown then GHCi can't do anything useful (no side-effects this time), so complains.
In this case, return "abc" typechecks as IO String, and String is an instance of Show, so GHCi does something like
it <- return "abc"
print it
which by the monad laws is exactly the same as just doing
print "abc"
hence the result.
Haskell has a slightly baffling set of rules for deciding the types of expressions involving numbers; you can see the Report section on ambiguous types and default instances. So the answer to the general question is complicated. But within GHCi, if you enter an expression e, you can rely on these rules to apply:
If the expression e can be typed as IO T for some type T, and if T has a Show instance, GHCi will run the computation and print the resulting value of type T. That's what's happening in your third example.
If the expression e *cannot* be typed in the IO monad, then the default-instance rules come into play, and GHCi will choose a type according to those rules. If the type has a Show instance GHCi will then print show e. That's what happens in your first two examples: Maybe String and [String] are pure values with Show instances.
If e's type does not have a Show instance, then GHCi will complain. That will happen if you type an expression like flip take.

learning type of argument in function

How can I learn type of argument at function in Haskell ? In python, we have type ( ) function.
Ex:
in func;
if type ( a ) == Int
do <something>
But, I don't know how I can manage that wish in Haskell ?
You don't need this since Haskell is statically typed and all types are known at compile time. In case of polymorphic functions like length :: [a] -> Int (Calculate the length of a list of elements of type a), there is no way to find out about the type of the argument, since you specified with the type that any argument type fits.
You have http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Typeable.html
However compared to dynamic languages it is very very rare that you need to use such means, and as beginner you shouldn't even try to use it, as you're almost certainly doing it wrong, even if you are sure that you need it. You should embrace Haskell's battle cry "Follow the type!" and express your thoughts using the type system instead of trying to subvert it.
If you are trying to do type-directed dispatch, then you probably want a typeclass.
data Bar = ...
class Foo a where
foo :: a -> Bar
instance Foo Int where
foo = ...
func :: Foo a => a -> ...
func x ... = ... foo x ...
Notice how the type signature demands that x is an instance of the Foo class. That means we can call foo on x and the type-directed dispatch will be done for us, in a type-safe way. If you write code that tries to call foo on something that is not an instance of Foo, then it will be a type error.
The reason you are not allowed to perform your own type-directed dispatch in Haskell is because that would break some important guarantees given to you by the type system. We would have to say goodbye to our theorems for free.

How to use quickcheck in main

I am writing a test for a binary search function I wrote.
module Tests where
import Data.List (sort)
import Test.QuickCheck
import BinarySearch (binarySearch)
prop_equals_elem x xs = (binarySearch x $ sort xs) == (x `elem` xs)
args = Args {replay = Nothing, maxSuccess = 200, maxDiscard=200, maxSize=200, chatty = False}
main = do
quickCheck (prop_equals_elem :: (Ord a) => a -> [a] -> Bool)
It works well using quickCheck in ghci but when I try to run main it gives the error
Tests.hs:12:5:
Ambiguous type variable `a0' in the constraints:
(Arbitrary a0) arising from a use of `quickCheckWith'
at Tests.hs:12:5-18
(Show a0) arising from a use of `quickCheckWith'
at Tests.hs:12:5-18
(Ord a0) arising from an expression type signature
at Tests.hs:12:26-72
Why does this not work in main but does in ghci?
This is likely caused by the extended defaulting rules in GHCi.
When testing a function like this, you need to use a concrete element type. GHCi will default the element type to () because of the extended rules, but this will not happen when compiling the code normally, so GHC is telling you that it cannot figure out which element type to use.
You can for example use Int instead for the test. () is pretty useless for testing this function, as all elements would be the same.
quickCheck (prop_equals_elem :: Int -> [Int] -> Bool)
If it works for Int, it should work for any type due to parametricity.
When you run a QuickCheck test, QuickCheck needs to know how to generate data. Here, you've told it only that your code should work with an arbitrary type of the Ord type class, which isn't enough for it to start testing. Hence the error about ambiguous type classes.
If you just need an arbitrary Ord instance, as it appears here, then something like Int would be a good choice for your testing. It's a simple type with a linear order. So try fixing your type to Int in main, as in:
quickCheck (prop_equals_elem :: Int -> [Int] -> Bool)
As for why it works in GHCi, the answer is defaulting. GHCi defaults type variables to () whenever possible, just to avoid giving spurious errors in situations where you really don't care about a value. Actually that's an awful choice: you won't test anything interesting by only testing with the () type! So again, the explicit type signature is better.

Resources