i'm playing a little with Haskell and i'm stuck with this error, using the snd function with a tuple (String, list).
snd ("Felix Felices",[("Escarabajos Machacados",52,[f1,f2]),("Ojo de Tigre Sucio",2,[f2])])
ERROR - Cannot find "show" function for:
*** Expression : snd ("Felix Felices",[("Escarabajos Machacados",52,[f1,f2]),("Ojo de Tigre Sucio",2,[f2])])
*** Of type : [([Char],Integer,[(Integer,Integer,Integer) -> (Integer,Integer,Integer)])]
The thing is, if i remove f1, f2 and f3 (they are functions) the code works just fine, it returns the list. Why is this happening, why can't i just put a function inside the tuple's second position?
You can put functions into tuples. But you can't display them - ghci wants to show the result and print it. How should it show (convert to string) the functions? It can't, or at least nobody felt like choosing one way of doing it (which would propably be flawed anyway - at least I can't think of any approach that doesn't have holes to huge even I can see them). Therefore, you can't evaluate something that returns functions or collections of functions in ghci.
The problem isn't really the functions f1 f2 or f3, the problem is that you are trying to print these functions, but functions don't have an instance of Show, so they cannot be printed. However if you try:
Prelude> snd ("Felix Felices",[("Escarabajos Machacados",52,["f1","f2"]),("Ojo de Tigre Sucio",2,["f2"])])
you get the result:
[("Escarabajos Machacados",52,["f1","f2"]),("Ojo de Tigre Sucio",2,["f2"])]
So the problem isn't that you cannot have a function in a tuple, the problem is that you cannot convert functions to strings so they can be printed.
module Text.Show.Functions provides an instance Show (a -> b).
ghci> :m +Text.Show.Functions
ghci> [(*), (/)]
[<function>,<function>]
It's not useful for actually figuring out what the functions are, but there's no good way to do that anyway (well, the debugger and vacuum aside). But if you just want some Show instances for convenience, this is in the standard library.
You cannot print bare functions in Haskell as there is no "show" function defined for them.
You get the same type of error, if you type
Hugs> sqrt
for example
The system tells the type of the expression, which in your case is ([Char],Integer,[(Integer,Integer,Integer) -> (Integer,Integer,Integer)])], but cannot print it, because it is a function.
Related
I'm restricting myself the use of prebuilt-in functions for training purposes. I have recoded length as count and it works.
I have a search funtion that simply returns a value at index in a list when given an index and a list. It works completly fine. It throws an error when the index is too large.
search [] _ = error "index too large"
search (a:_) 0 = a
search (_:a) b = search a (b - 1)
Now, I want a safeSearch function that return Nothing if the index is too large of if the list is empty. So I've simply done this.
safeSearch :: [a] -> Int -> Maybe a
safeSearch a b
| b < 0 || b >= count a = Nothing
| otherwise = Just (search a b)
And it works! ... as long as you don't try it on an empty list. Even with an index too large for the list length.
main = print(safeSearch [] 5)
This crashes and I really can't find any way around it.
Even though I don't think my second line is usefull (because if the list is empty, its count is 0 so we drop in the first guard and it should return Nothing?) its not working. Removing it does not solve the problem.
Here's the compile-time error.
main.hs:91:8: error:
* Ambiguous type variable `a0' arising from a use of `print'
prevents the constraint `(Show a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance Show Ordering -- Defined in `GHC.Show'
instance Show Integer -- Defined in `GHC.Show'
instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
...plus 22 others
...plus 13 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In the expression: print (safeSearch [] 5)
In an equation for `main': main = print (safeSearch [] 5)
|
91 | main = print(safeSearch [] 5)
| ^^^^^^^^^^^^^^^^^^^^^^
exit status 1
Any idea? Something I'm missing or even completly going wrong? A concept I need to understand deeper?
The problem is a compile error. That means it isn't actually running your code and hitting your error "index too large" call; the compiler is rejecting your code before it can even try to run it. So you're looking in the wrong place if you're trying to change the code to avoid that.
What's actually happening is that safeSearch [] 5 is returning a value of type Maybe a, where a is the type of the elements in the list. But you didn't include any elements in the list, so there is nothing at all to decide what that type a is.
Your function safeSearch can work for any type, so that's actually fine. But you also try to print the Maybe a value. Using print requires a Show instance, and the instance for Maybe a requires there to also be a Show instance for a. Because there is nothing saying what type a is, the compiler has no way of finding the appropriate Show instance for it, so it has to abort compilation with an error.
The most straightforward way to solve it is to add a type annotation (either of the list, or the Maybe a value resulting from safeSearch). Something like this:
main = print (safeSearch ([] :: [Int]) 5)
(This is what the error message is talking about when it says an ambiguous type variable is preventing a Show constraint from being solved, and that the probable fix is to add a type annotation)
Note that this sort of issue is rarely a problem in "real" code. Normally if you have a list processed into another structure with a related type, you will have other code that does something with the elements or the result, or that produced the list (which isn't always empty). You wouldn't normally write a program that does nothing but process an always-empty list and print the result, except for these kinds of quick tests. So normally, when there is that other code as well, there will be enough context for the compiler to deduce the type of your empty list, and the extra type annotations will not be needed. So this kind of extra type annotation is not usually considered a serious burden that needs to be avoided, because they are hardly ever needed in "real" code. You just code as you want, and on the occassion that a compile error makes your realise you need an annotation you simply add it and move on.
If you do this kind of quick check in GHCi rather than writing a full program with a main function, then you also would not have needed the extra type annotation. This is because GHCi has the ExtendedDefaultRules language extension turned on by default. The "default rules" are conditions when GHC will choose a type for you instead of throwing an "ambiguous type" error. The normal default rules are pretty strict, and really only designed for defaulting numeric constraints (like Num a or Real a, etc). They do not apply to your original example. The "extended default rules" apply more often to avoid needing lots of type signatures in the interactive interpreter (since there you enter one line at a time, instead of the compiler being able to see the full module to infer types from usage). In this case entering print (safeSearch [] 5) at the interpreter prompt will work because it defaults the returned type to Maybe (), and it just so happens that printing Nothing :: Maybe () produces the same output as it would if it had correctly guessed the type you actually meant.
But in almost any real program, defaulting a type variable to () will be a stupid thing to do that makes things work less, so I do not recommend getting into the habit of enabling ExtendedDefaultRules in an actual module. Just add the type annotation, or do quick checks in the interpreter instead of in a module.
What you've written works great for any real-world use case. It only fails when someone writes print (safeSearch [] x) - a literal empty list, with no context to tell what result type is expected. It works fine if they pass in a nonempty list, or a list expression that happens to evaluate to an empty list, or if they use the result in a way that lets type inference figure out what was intended.
Further, there is really no way to write the function so that it works when passed a contextless empty list. The burden to make the types clear is necessarily placed on call sites, not the definition. The comments on your question have already shown how to do this; you only have to be that explicit when you're calling your function in a way that's obviously useless.
I'm new to haskell.
Sometimes I write some complicated functions that I'm not so sure about the types myself, so I don't define its type beforehand, compiling and running still work fine.
I want to know if I can print out the types of that function like in "ghci> :info someFunc" in the program, just to see how Haskell define its. Maybe something like this:
f x = 2*x
main :: IO()
main = do
print_info f
I know I can "ghci> :load program.hs" & then ":info f", but for me it is quite unconvenient & sometime working with ghci can be ugly.
Can't be done. You can sort of get close with Typeable, but polymorphism cannot be captured, even in principle.
Instead, I recommend that you set up the Haskell Language Server and connect your editor to it; most editors support at least the level of connection that lets you hover a term to see its type or add a type signature to a definition with a keybinding.
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? :-(
I'm trying to learn Haskell by writing a simple console chess game. It displays a chess board and gets moves from standard input in SAN notation. Here's what I've got so far:
import System.IO
import Chess
import Chess.FEN
main = do
putStrLn "Welcome to Console Chess!"
putStrLn $ show defaultBoard
gameLoop defaultBoard
gameLoop board = do
putStr "Your move: "
hFlush stdout
move <- getLine
let newBoard = moveSAN move board
case newBoard of
Left _ -> do
putStrLn "Invalid move, try again..."
gameLoop board
Right b -> do
putStrLn $ show b
gameLoop b
The problem is that the call to the moveSAN function sometimes crashes the program, losing all progress made in the game. For instance, pressing Enter at the "Your move:" prompt produces:
Your move:
cchess: Prelude.head: empty list
Otherwise, entering a two-digit number produces:
Your move: 11
cchess: Error in array index
Entering two periods gives:
Your move: ..
cchess: Char.digitToInt: not a digit '.'
I would like to catch these errors and inform the user that the move they have entered is not in valid SAN notation. How can I do that?
In an ideal world, you would avoid functions like head and not have runtime errors at all. Runtime errors are fundamentally awkward, especially in Haskell.
In this case, you want to catch the runtime error. If you're content to turn it into a Maybe, you can use the spoon package.
Exceptions in Haskell are subtle thanks to laziness. Particularly, if you don't evaluate the part of the structure that has the exception, it won't fire. This is handled in spoon with two different functions:
spoon, which evaluates a structure deeply but requires an instance of a special typeclass
teaspoon which only evaluates your structure part of the way to weak head normal form
For your case, I think teaspoon should be fine. Try checking the result of the parse with:
teaspoon (moveSAN move board)
which should give you a Maybe value.
If that doesn't work, it means you need to evaluate more of the structure to hit the exception. It looks like Board does not implement the typeclass needed to deeply evaluate it with spoon, so your best bet is a bit hacky: use spoon on the result of show:
spoon (show $ moveSAN move board)
This will give you a Maybe String. If it's Just, the move parsed correctly; if it's Nothing, there was an error.
It's worth noting that the spoon package doesn't really do much: each function it has is only a couple of lines. At some point, it's worth figuring out how to handle exceptions in Haskell yourself, but for now spoon is just a bit more convenient and should work properly for you.
I need to create a function f:: Log->[String] that does that (((o, i ,d),s) = [(o, i ,d)]
type Log = (Plate, [String])
type Plate = (Pin, Pin, Pin)
type Pin = (Char, Int)
If you're on a page like this, click "Source" on the fir right side, next to the function that you're interested in.
If you need to look up a function, Hayoo! and Hoogle will link you to documentation pages like the one above.
An important thing to note, though is that show doesn't have one definition. show is a function defined for all data types in the Show (with a capital "S") typeclass. So for example, here is the full source for the Show typeclass. Show is defined within the typeclass as just show :: a -> String. But if you search for "instance Show Bool" or "instance Show Int", you'll find specific definitions.
For the second part of your question, the easiest way to get a show function for a new type is to simply write deriving (Show) below it. For example,
data Foo = Foo Int Int
deriving (Show)
Now I can use show on data with type Foo.
g :: Log -> [String]
g (plate, _) = [show plate]
Use hoogle to find this sort of information.
Example: http://www.haskell.org/hoogle/?hoogle=show
Once you've found the function you'd like in the list, click and there you'll find a Source link on the right hand side of the page.
NB this is an answer to the original question:
Where can I see the codes of the predefined functions in haskell ?? Mainly the function SHOW?
It's true that you can use Hoogle to search for functions defined in the Prelude (and other modules), but the source code itself is located at Hackage.
Hackage is a database of Haskell packages. You can download new packages from it, and also view the Haddock documentation for every package in the database.
This is the Haddock page for the standard Prelude. It documents the type classes, data types, types, and top-level functions exported by the Prelude module. To the right of each definition header is a link that says "Source". You can click this to be taken to an online copy of the source code for the module you're viewing.
On preview, you're now asking a different question entirely, and on preview again in fact the original question has been edited out of this post.
Your new question is unclear, but this solution will work to produce the output in your example.
> [fst ((('O',0),('I',0),('D',1)),"O->D")]
[(('O',0),('I',0),('D',1))]
I think you're using list notation instead of double quotes to identify Strings, by the way, so I fixed that around 0->D above. So you might also try this instead.
> show (fst ((('O',0),('I',0),('D',1)),"O->D"))
"(('O',0),('I',0),('D',1))"
This works because you have only defined type synonyms (by using type in your declarations instead of data) on data structures which already have Show instances.