`inferior-haskell-type` inside a `where` clause? - haskell

Does haskell-mode or some alternative package offer something akin to the wonderful inferior-haskell-type inside a where clause?
For example, suppose I have
foo = undefined where
bar = complicated
...
it would be super-awesome to be able to place the marker at bar and inspect its type.

This is possible with Scion in combination with Emacs.
C-c C-t shows type of identifier at point. This only works if the current file typechecks, but then it also works for local identifiers. For polymorphic function it will show the type to which they are instantiated, e.g.,
f x = x + (1::Int)
Calling this command on + will print Int -> Int -> Int instead of Num a => a -> a -> a.

Related

Type class Read, is it posibble to read a function by it name?

Suppose I have this function:
squared x = x ** 2
and I want to read it from the console, and apply it. Is possible to do something like this?:
gchi> (read("squared) :: Int -> Int) 4
No; in general, this is not possible. To see why, think about a few of the situations which could occur if this functionality existed:
Let’s say you redefine (+) a b = a - b. Now, should read "(+)" be the (+) from the Prelude, or your redefined (+) operator?
If you do read "foobar", and foobar has not yet been defined as a function, then what should this return? Then if foobar is defined somewhere else in the module, should this return value suddenly change?
If you add import Prelude () to the top of your program, which removes all of the imports from Prelude, should read "preludeFunctionName" stop working?
Now, none of these problems are dealbreakers in and of themselves — in another language, you could still define a read function taking those into account. The problem in this case is referential transparency : the property that a non-IO function should always return the same output given the same input(s). Since the type of read is Read a => String -> a, as opposed to Read a => String -> IO a, you can’t make an instance of read like you want, given that the above function can give a different answer depending on the exact context in which it is run. (e.g. read "foobar" and let foobar = (+1) in read "foobar" would give different answers to the same function call.)
On the other hand, if you still want to have this functionality, there is one way of getting it. The hint package allows Haskell code to be interpreted at runtime, and so you can use this functionality to write a function like this:
-- Warning: the following code is untested
-- Please comment if you find any errors!
import Language.Haskell.Interpreter
readFn :: Typeable a
=> [ModuleName] -- ^ Modules to search
-> String -- ^ Function to read
-> a -- ^ Witness for the type a
-> IO (Either InterpreterError a)
readFn m f w = runInterpreter $ do
setImports m
interpret f w
The above function can be used as follows:
readFn ["Prelude"] "(+)" (as :: Num a => a -> a -> a)
Where as is from Language.Haskell.Interpreter.

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.

Different numbers of arguments when pattern matching Maybe

I've run into a problem I don't really understand. I thought that I would be able to write code like this in Haskell:
foo :: Maybe Int -> Int
foo Nothing = 0
foo Just x = x
But when I try to compile it, I get the error:
Equations for ‘foo’ have different numbers of arguments
I can fix it by changing my code to the following:
foo :: Maybe Int -> Int
foo Nothing = 0
foo (Just x) = x
Which makes me think that GHC is interpreting Just as an argument to foo. But Haskell forbids using uppercase letters to start variable names, so I wouldn't think there should be any ambiguity here. What's going on?
You're correct, there's not ambiguity about whether or not Just is a constructor – but constructors can have no arguments! Haskell's pattern matching doesn't look up the names involved, it's strictly syntactic, and foo Just x = x is a perfectly well-formed function definition clause. It's ill-typed:
Prelude> let foo Just x = x
<interactive>:2:9:
Constructor ‘Just’ should have 1 argument, but has been given none
In the pattern: Just
In an equation for ‘foo’: foo Just x = x
but with different data types around, it'd be fine:
Prelude> data Justice = Just
Prelude> let foo Just x = x
Prelude> :t foo
foo :: Justice -> t -> t
Prelude> foo Just ()
()
Just could be a nullary constructor (as in the second example), and since function application is left-associative, the compiler parses Just and x as separate arguments and you get the "different numbers of arguments" error. (And as you can see above, if there weren't the Nothing case, you'd actually get the type error for code of that form.)
The idea is that pattern syntax should mirror application syntax. If I was calling foo I couldn't write foo Just x, because that means something else (and if foo had type (Int -> Maybe Int) -> Int -> Int then it would even work). Having patterns have different rules for where parentheses are needed than expressions would be very weird.
Writing compound patterns without parentheses and trusting the compiler to automatically group things also falls apart in more complex situations. What should this mean?
foo Just x : xs = ...

Apply polymorphic function in a GHC plugin

I would like to write a GHC plugin which "adds a hook" to each function. Say I want to apply a function addHook of type Ord a => (a -> b) -> a -> b to the right-hand side of each function binding, transforming
foo = [RHS]
into
foo = addHook [RHS]
This works fine if I'm only interested in adding hooks to functions of type Int -> Int, in which case I make addHook also to have type (Int -> Int) -> Int -> Int, and invoke mkCoreApp [AddHook] [RHS] and bind it to foo in my GHC plugin.
However, if I want addHook to be polymorphic as described above, the transformed GHC Core for an Int -> Int function should look like
foo = addHook # GHC.Types.Int # GHC.Types.Int GHC.Classes.$fOrdInt [RHS]
Notice that there should be some type information attached, but I cannot find a way to construct these in the plugin, and GHC panics without those. Any suggestion would be appreciated.

SML conversions to Haskell

A few basic questions, for converting SML code to Haskell.
1) I am used to having local embedded expressions in SML code, for example test expressions, prints, etc. which functions local tests and output when the code is loaded (evaluated).
In Haskell it seems that the only way to get results (evaluation) is to add code in a module, and then go to main in another module and add something to invoke and print results.
Is this right? in GHCi I can type expressions and see the results, but can this be automated?
Having to go to the top level main for each test evaluation seems inconvenient to me - maybe just need to shift my paradigm for laziness.
2) in SML I can do pattern matching and unification on a returned result, e.g.
val myTag(x) = somefunct(a,b,c);
and get the value of x after a match.
Can I do something similar in Haskell easily, without writing separate extraction functions?
3) How do I do a constructor with a tuple argument, i.e. uncurried.
in SML:
datatype Thing = Info of Int * Int;
but in Haskell, I tried;
data Thing = Info ( Int Int)
which fails. ("Int is applied to too many arguments in the type:A few Int Int")
The curried version works fine,
data Thing = Info Int Int
but I wanted un-curried.
Thanks.
This question is a bit unclear -- you're asking how to evaluate functions in Haskell?
If it is about inserting debug and tracing into pure code, this is typically only needed for debugging. To do this in Haskell, you can use Debug.Trace.trace, in the base package.
If you're concerned about calling functions, Haskell programs evaluate from main downwards, in dependency order. In GHCi you can, however, import modules and call any top-level function you wish.
You can return the original argument to a function, if you wish, by making it part of the function's result, e.g. with a tuple:
f x = (x, y)
where y = g a b c
Or do you mean to return either one value or another? Then using a tagged union (sum-type), such as Either:
f x = if x > 0 then Left x
else Right (g a b c)
How do I do a constructor with a tuple argument, i.e. uncurried in SML
Using the (,) constructor. E.g.
data T = T (Int, Int)
though more Haskell-like would be:
data T = T Int Bool
and those should probably be strict fields in practice:
data T = T !Int !Bool
Debug.Trace allows you to print debug messages inline. However, since these functions use unsafePerformIO, they might behave in unexpected ways compared to a call-by-value language like SML.
I think the # syntax is what you're looking for here:
data MyTag = MyTag Int Bool String
someFunct :: MyTag -> (MyTag, Int, Bool, String)
someFunct x#(MyTag a b c) = (x, a, b, c) -- x is bound to the entire argument
In Haskell, tuple types are separated by commas, e.g., (t1, t2), so what you want is:
data Thing = Info (Int, Int)
Reading the other answers, I think I can provide a few more example and one recommendation.
data ThreeConstructors = MyTag Int | YourTag (String,Double) | HerTag [Bool]
someFunct :: Char -> Char -> Char -> ThreeConstructors
MyTag x = someFunct 'a' 'b' 'c'
This is like the "let MyTag x = someFunct a b c" examples, but it is a the top level of the module.
As you have noticed, Haskell's top level can defined commands but there is no way to automatically run any code merely because your module has been imported by another module. This is entirely different from Scheme or SML. In Scheme the file is interpreted as being executed form-by-form, but Haskell's top level is only declarations. Thus Libraries cannot do normal things like run initialization code when loaded, they have to provide a "pleaseRunMe :: IO ()" kind of command to do any initialization.
As you point out this means running all the tests requires some boilerplate code to list them all. You can look under hackage's Testing group for libraries to help, such as test-framework-th.
For #2, yes, Haskell's pattern matching does the same thing. Both let and where do pattern matching. You can do
let MyTag x = someFunct a b c
in ...
or
...
where MyTag x = someFunct a b c

Resources