Haskell, how to run this? - haskell

I have this code :
divideByTen :: (Floating a ) => a -> a
divideByTen = (/10)
If I put this into .hs file. Seems this is not enough.
(I use ghci on Mac osx).
Thank you.
After I did :load **.hs
I got this error
byby.hs:1:17:
Class `Floating' used as a type
In the type signature for `divideByTen':
divideByTen :: (Floating a) a -> a
Failed, modules loaded: none.

The way you showed in the code slice is fine, but your error clearly shows you're missing a => in your type signature.
In the future please copy/paste your code in question. If you did then perhaps your editor has converted => to Unicode or some other transformation.

The problem is that the arrow => seems to get dropped somewhere, as evidenced by the absence of this arrow in the type signature given for divideByTen in the error message GHC spouts back.
Make sure that the content of your .hs file matches the code snippet you gave above exactly, and it should be fine.

As it's written, your code works for me.
Are you using an ide that might do odd transformations on the source code? Go to a command line and dump the content of the file to check.
How are the lines indented? Is there any other code in your file? Whitespace can change how lines are parsed in Haskell.

Related

Require that a specific Haskell type defined in code is invalid

Is it possible to instruct GHC compiler to require that a specific value in code has invalid type, without ever using this value?
A contrived example is:
data Box a = Num a => Box a
goodBoxSample :: Box Int
goodBoxSample = Box 1
-- below definition and binding are expected to fail compilation
badBoxSample :: Box String
badBoxSample = Box "foo"
Is there a way to inform the compiler that badBoxSample is expected to fail (e.g. with some pragma, rather than commenting it out as a known bad sample), so that the code compiles only if badBoxSample fails to type-check?
The motivation here is the same as for writing a test (in some other language) with the code that is required to throw exception for the test case to pass.
Not possible. You're basically asking for a way to prove that there's no instance Num String, but Haskell operates under the open-world assumption, which means that someone could always declare such an instance.
Somebody posted a very helpful answer here, but before I managed to accept it was removed... Thank you anyway, and here it is for the reference:
https://hackage.haskell.org/package/generic-lens-2.0.0.0/docs/Data-Generics-Product-Fields.html
In short, the goal of testing failing types can be achieved with doctest, in the way the linked library does it.

Basic error in Paskell

I've just started to try and learn Haskell, and I have encountered a problem. I am using windows CMD and I have created a program.hs .txt file for my first program, which includes a simple a + b function. I have written answer = a + b in the txt file, and then I opened the GHCI in CMD. I loaded my program successfully, but when I typed answer 1 5 instead of returning 6 it returns
Variable not in scope: answer :: Integer -> Integer -> t
Please can you help and explain it to me. Thanks.
It seems that you did not load the file correctly. Maybe you loaded another file? It's hard to tell.
"Not in scope" in GHCi means that the module you loaded (if any) does not export that variable.
Further, your Haskell code is wrong. answer = a + b assumes that variables a and b are already defined when you load the module, e.g. they have been defined there. This will trigger a "not in scope" error for those variables.
If you intend answer to be a function, then you need to define it as a function, e.g.
answer a b = a + b
-- ^^^ --
Note the additional arguments.

Haskell: Parse error: module header, import declaration or top-level declaration expected

I am saving some commands in a Haskell script in a .hs file while working thru a Haskell textbook. Here's a small example.
fst (1,2)
snd (1,2)
When I run these commands from the prelude in GHCi, they work fine. When I try to compile the .hs file with these two lines, I get the following:
ch4_test.hs:2:1: error:
Parse error: module header, import declaration
or top-level declaration expected.
|
2 | fst (1,2)
| ^^^^^^^^^
Failed, no modules loaded.
I've googled this error and can't find any explanation what I'm doing wrong.
From a newbie to future newbies: The interactive environment ghci would lead you to believe that you can punch some expressions into an .hs file and run the thing (in a similar fashion to languages like swift and ruby). This is not the case.
Haskell needs an entrypoint called main. Quoting:
Here is a simple program to read and then print a character:
main :: IO ()
main = do c <- getChar
putChar c
The use of the name main is important: main is defined to be the entry point of a Haskell program (similar to the main function in C), and must have an IO type, usually IO ()
Source: https://www.haskell.org/tutorial/io.html
You can't just put any expression in a hs file.
As the error message says, you need a declaration here. For example:
main =
print (fst (1,2)) >>
print (snd (1,2))
I am getting this error but the cause appears to be completely different from anything posted here. And the error message is not at all helpful.
Using Cabal version 3.6.2.0 with GHCI 8.10.7 on MacOS High Sierra (10.13)
I'm working from this page: https://www.tutorialspoint.com/haskell/haskell_modules.htm
specifically the "custom modules" section. There you can see the code I copied and pasted.
Besides the tutorial not mentioning I needed to add "other-modules: Custom" to myfirstapp.cabal, and besides the fact that the sample Custom.hs file includes "if x 'rem' 2 == 0" rather than "if x rem 2 == 0", here is the problem:
Indentation matters!
This line (inside the quotes) does NOT work "if x rem 2 == 0".
This line DOES work " if x rem 2 == 0"!
Indenting by one space is the difference between success and failure.
I'm totally new to Haskell. I've programmed extensively in PHP, Javascript, and Applescript, and dabbled in a dozen others, and this is the first time I've seen white space matter. I assume this is commonly known amongst Haskell veterans, but it would certainly be nice if that was included prominently in the documentation.

How to introspect an Haskell file to get the types of its definitions

I have many files that must be processed automatically. Each file holds the response of one student to an exercise which asks the student to give definitions for some functions given a type for each function.
My idea is to have an Haskell script that loads each student file, and verifies if each function has the expected type.
A constraint is that the student files are not defined as modules.
How can I do this?
My best alternative so far is to spawn a GHCi process that will read stdin from a "test file" with GHCi commands, for example:
:load student1.hs
:t g
... and so on ...
then parse the returned output from GHCi to find the types of the functions in the student file.
Is there another clean way to load an arbitrary Haskell file and introspect its code?
Thanks
Haskell does not save type information at runtime. In Haskell, types are used for pre-runtime type checking at the static analysis phase and are later erased. You can read more about Haskell's type system here.
Is there a reason you want to know the type of a function at runtime? maybe we can help with the problem itself :)
Edit based on your 2nd edit:
I don't have a good solution for you, but here is one idea that might work:
Run a script that for each student module will:
Take the name of the module and produce a file Test.hs:
module Test where
import [module-name]
test :: a -> b -> [(b,a)]
test = g
run ghc -fno-code Test.hs
check the output does not contain type errors
write results into a log file
I think if you have a dynamically determined number of .hs files, which you need to load, parse and introspect, you could/should use the GHC API instead.
See for example:
Using GHC API to compile Haskell sources to CORE and CORE to binary
https://mail.haskell.org/pipermail/haskell-cafe/2009-April/060705.html
These might not be something you can use directly — and I haven't done anything like this myself so far either — but these should get you started.
See also:
https://wiki.haskell.org/GHC/As_a_library
https://hackage.haskell.org/package/hint
The closest Haskell feature to that is Data.Typeable.typeOf. Here's a GHCi session:
> import Data.Typeable
> typeOf (undefined :: Int -> Char)
Int -> Char
> typeOf (undefined :: Int -> [Char])
Int -> [Char]
> typeOf (undefined :: Int -> Maybe [Char])
Int -> Maybe [Char]
> :t typeOf
typeOf :: Typeable a => a -> TypeRep
Under the hood, the Typeable a constraint forces Haskell to retain some type tags until runtime, so that they can be retrieved by typeOf. Normally, no such tags exist at runtime. The TypeRep type above is the type for such tags.
That being said, having such information is almost never needed in Haskell. If you are using typeOf to implement something, you are likely doing it wrong.
If you are using that to defer type checks to run time, when they could have been performed at compile time, e.g. using a Dynamic-like type for everything, then you are definitely doing it wrong.
If the function is supposed to be exported with a specific name, I think probably the easiest way would be to just write a test script that calls the functions and checks they return the right results. If the test script doesn't compile, the student's submission is incorrect.
The alternative is to use either the GHC API (kinda hard), or play with Template Haskell (simpler, but still not that simple).
Yet another possibility is to load the student's code into GHCi and use the :browse command to dump out everything that's exported. You can then grep for the term you're interested in. That should be quite easy to automate.
There's a catch, however: foo :: x -> x and foo :: a -> a are the same type, even though textually they don't match at all. You might contemplate trying to normalise the variable names, but it's worse: foo :: Int -> Int and foo :: Num x => x -> x don't look remotely the same, yet one type is an instance of the other.
...which I guess means I'm saying that my answer is bad? :-(

Is it a bad idea to use [Char] instead of String in Haskell function type declaration

I have just started learning Haskell using "Learn you a Haskell for Great Good".
I am currently reading "Types and Typeclasses" chapter, so my knowledge is pretty .. non-existent.
I am using Sublime Text 2 with SublimeHaskell package which builds/checks file on every save.
The problem: I'm trying to make function type declaration like this:
funcName :: [Char] -> [Char]
I'm getting this warning:
Warning: Use String
Found:
[Char] -> [Char]
Why not:
String -> String
Build FAILED
Can you explain to me why is it a bad idea to use Char array instead of String or give me a link to an explanation of possible repercussions etc. I've googled and found nothing.
P.S. I'm a C# developer, I understand the difference between char array and strings in c-like languages.
Somewhere in the base library you will find this definition:
type String = [Char]
which says that String and [Char] are exactly the same thing. Which of the two you choose is a documentation choice. I often define type aliases like this:
type Domain = ByteString
type UserName = Text
It's a good idea to use types for documentation.
Also as an important side note, [Char] is not the type for character arrays, but character lists. Since there are also actual array types, the distinction is important!
String is nothing more than a type alias for [Char], so there is no practical between the two - it's simply a matter of readability.
You seem to be running HLint on your code automatically, and treating any HLint warnings as fatal errors. As the HLint author says "Do not blindly apply the output of HLint". String and [Char] are exactly the same, as everyone says, it's a question of which looks nicer. I would tend to use String if I'm operating on contiguous lists of characters I want to treat as a block (most of the time), and explicitly use [Char] when the characters don't make sense combined in a run (far rarer). HLint divides all hints into error (fix) and warning (think), so perhaps it might be best only to build fail on error hints.

Resources