What are the rules regarding naming in Haskell? - haskell

Are there definite rules regarding naming of entities in Haskell? (by entities I mean functions, term level variables, data constructors, type variables, type constructors, typeclasses, modules; not sure if I left something out here) For example
<interactive>:1:13: error:
Not in scope: type constructor or class ‘Zed’
Perhaps you meant type variable ‘zed’ (line 1)
I know that in type signatures concrete types must be uppercase. So is it assuming that Zed is a concrete type, and because this type isn't defined (isn't in scope), we get an error?
Are there any other actual rules on naming stuff in Haskell?

As was pointed out by M. Aroosi in a comment, your errors don't match your example – you seem to have written f :: zed -> Zed : f = undefined instead, with a : instead of a ;. If you use a ; you will get one of two results. If Zed is undefined, you'll get an error telling you so:
Prelude> f :: zed -> Zed ; f = undefined
<interactive>:2:13: error:
Not in scope: type constructor or class ‘Zed’
Perhaps you meant type variable ‘zed’ (line 2)
If Zed is defined, everything will work:
Prelude> data Zed = TheZed
Prelude> f :: zed -> Zed ; f = undefined
Prelude>
The general rule for Haskell names is:
At the type level:
Type names start with an uppercase letter.
Type variables start with a lowercase letter.
At the term level:
Constructor names start with an uppercase letter if they're ordinary names.
Constructor infix operators start with a :.
Variable names start with a lowercase letter if they're ordinary names.
Variable infix operators start with anything but a :.
There are some further wrinkles (e.g., you can't use , in names; you can't have a name that's only -s and 2 or more character long), but that covers 95% of it.

You are using the REPL (Ghci). If you try to use a type signature in the REPL, you need to use :{ .....\n ..... \n ..... :} kind of multiline input. Then you can do the type signature of the function along with implementation(s) of that type signature. Its not very practical - 1 typo and you have to do it all over again. (Julia language REPL does a much better job with that, btw.).
And yes, there are style guides and types need to start with an uppercase. Usually the compiler warns/errors you.
Since you seem to start out, I suggest you use a source file for your experiments because as soon as you end up with multiple line constructs, the REPL kind of sucks. And it is really easy to use a file for your code. See :load :cd :reload etc. for your GHCI commands which support you doing that.

Related

How to approach compilation errors with internal Text modules?

I have this problem:
Couldn't match expected type ‘case-insensitive-1.2.0.5:Data.CaseInsensitive.Internal.CI
Text’
with actual type ‘Text’
In the first argument of ‘named’, namely ‘n’
because:
Prelude Text.XML.Lens> :t named
named
:: Applicative f =>
case-insensitive-1.2.0.5:Data.CaseInsensitive.Internal.CI
Data.Text.Internal.Text
-> (Element -> f Element) -> Element -> f Element
My code imports Data.Text and relies on OverloadedStrings. What steps should I take to resolve issues like this? What are short term and long term fixes?
Thanks to commenters as I was able to find out why I'm having this problem.
Short Answer: Pay close attention to types and make sure you understand them (read documentation of any module you see in error message).
Long Answer:
Notice that the type contains spaces and GHC may break them down to multiple lines. CI.Text is means something different than CI Text.
‘case-insensitive-1.2.0.5:Data.CaseInsensitive.Internal.CI
Text’
Text here is not a type synonym of re-exported internal Text (common practice in libraries). CI is a type constructor and you cannot import it (for a reason - you have to stop and read documentation of anything you touch). You will understand why you can import CI type and smart-constructors like mk instead.

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? :-(

Function names with symbol characters makes Googling difficult

In Haskell, many function names contain only symbol characters. Like $$, >>=, >>, :, ->, =>, =~.
Since I am new to Haskell, I am finding it difficult to search their meanings in Google. For example, to understand what -> means in Haskell, I need to use the search string hyphen followed by greater than which is not the best approach, as per me.
Is there a place that I could search for functions with symbols only?
Yes, this is a known bug with Google. You might consider a better search engine like Hoogle.
In general you need to look up the documentation for the actual function. To do this, you need to know what module it's defined in. The easiest way to determine this is to load up your source file in GHCi (so that you have all of its imports etc.) and then ask for the operator's :info thusly:
Prelude> :info (>>=)
class Monad (m :: * -> *) where
(>>=) :: m a -> (a -> m b) -> m b
...
-- Defined in ‘GHC.Base’
infixl 1 >>=
Prelude>
If the type signature is not enough, then this also tells you that you need to google the GHC.Base module, and the Monad typeclass. By itself that's pretty googleable, but if that typeclass keyword weren't there, what you would do is to google GHC.Base, the first result leading to the base package overview page. Once you are there1 then you look for a little link labeled [Index] beneath the module listing (GHC.Base has a huge module listing so in this case it's easier to miss).
Clicking that link takes you to an index of all the public symbols in that package; you can click the > character to find all operators beginning with a greater than sign. You will then have three links of modules which export that function; click on one and Ctrl-F to find the following documentation:
(>>=) :: forall a b. m a -> (a -> m b) -> m b | infixl 1 | Source
Sequentially compose two actions, passing any value produced by the first
as an argument to the second.
Again, Hoogle does all of this rigamarole for you and has some other nifty features like searching-by-type-signature.
For things like <-, ->, and => which are not functions, you will just have to know the language. The meaning of <- ("from") is from "do-notation", which you can Google; the meaning of -> ("to") varies depending on whether it appears in lambda-notation (like \a b -> b), case-expressions, or the type signature of a function (where a -> b -> c means "a function which takes an a and returns a function which takes a b and returns some c". The meaning of => is from "constraints" or "type classes" in Haskell.
Other than ->, you can sometimes see operators appearing in type signatures, too. These should be searchable by the above procedure.
This is assuming a stable API for the package. If the API has changed you will need to look up with ghc -v which package version the file is using, then click on that version.

Syntax rules for Haskell infix datatype constructors

I'm trying to make a Haskell datatype a bit like a python dictionary, a ruby hash or a javascript object, in which a string is linked to a value, like so:
data Entry t = Entry String t
type Dictionary t = [Entry t]
The above code works fine. However, I would like a slightly nicer constructor, so I tried defining it like this:
data Entry t = String ~> t
This failed. I tried this:
data Entry t = [Char] ~> t
Again, it failed. I know that ~ has special meaning in Haskell, and GHCi still permits the operator ~>, but I still tried one other way:
data Entry t = [Char] & t
And yet another failure due to parse error. I find this confusing because, for some inexplicable reason, this works:
data Entry t = String :> t
Does this mean that there are certain rules for what characters may occur in infix type constructors, or is it a cast of misinterpretation. I'm not a newbie in Haskell, and I'm aware that it would be more idiomatic to use the first constructor, but this one's stumping me, and it seems to be an important part of Haskell that I'm missing.
Any operator that starts with a colon : is a type constructor or a data constructor, with the exception of (->). If you want the tilde, you could use :~>, but you're not going to get away with using something that doesn't start with a colon. Source

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