So I'm working through some initial chapter exercise of Real World Haskell and I wanted to know if there is an option in GHCi to make it show function evaluation with parameters on each recursive call. So for example I wrote a simple version of 'map', and when I apply it, I would like GHCi to display each recursive call with actual arguments (and hopefully expression results). Something which allows me to follow whats going on behind the scenes.
P.S. As I write this I have a feeling it may be limited by the laziness of haskell's execution model, correct me if I'm wrong.
You can use hood for this:
import Debug.Hood.Observe
map2 f [] = []
map2 f (x:xs) = f x : (observe "map2" $ map2) f xs
main = runO $ print $ map2 (+1) ([1..10] :: [Int])
When you run it, it will print each call to map2 with the corresponding arguments and the result that was returned. You'll see something like:
.
.
.
-- map2
{ \ { \ 10 -> 11
, \ 9 -> 10
} (9 : 10 : [])
-> 10 : 11 : []
}
-- map2
{ \ { \ 10 -> 11
} (10 : [])
-> 11 : []
}
-- map2
{ \ _ [] -> []
}
For more check the examples.
I typically use Debug.Trace:
import Debug.Trace
buggy acc xs | traceShow (acc,xs) False = undefined
buggy acc [] = acc
buggy acc (x:xs) = buggy (acc + x) xs
main = print $ buggy 0 [1..10]
This lets me see how the buggy function works:
(0,[1,2,3,4,5,6,7,8,9,10])
(1,[2,3,4,5,6,7,8,9,10])
(3,[3,4,5,6,7,8,9,10])
(6,[4,5,6,7,8,9,10])
(10,[5,6,7,8,9,10])
(15,[6,7,8,9,10])
(21,[7,8,9,10])
(28,[8,9,10])
(36,[9,10])
(45,[10])
(55,[])
55
The key is having a pattern that never matches, but prints something while it's not matching. That way it always gets evaluated (and hence prints the debugging information), and it's easy to tack on to any function. But you can also make it match if you only want to see certain cases, like:
buggy acc [] = acc
buggy acc (x:xs) | traceShow (acc, x, xs) True = buggy (acc + x) xs
Then you only get debugging output at the non-base-case:
(0,1,[2,3,4,5,6,7,8,9,10])
(1,2,[3,4,5,6,7,8,9,10])
(3,3,[4,5,6,7,8,9,10])
(6,4,[5,6,7,8,9,10])
(10,5,[6,7,8,9,10])
(15,6,[7,8,9,10])
(21,7,[8,9,10])
(28,8,[9,10])
(36,9,[10])
(45,10,[])
55
YMMV.
I would recommend looking at the question How do I get a callstack in Haskell?, and Don Stewart's answer with linked guides on how to use ghci for debugging
Related
I want it to use library-defined partialfunc more convenient, or write callback with partial pattern-matching.
like this,
partialMaybe :: forall a b. (Partial => a -> b) -> a -> Maybe b
I couldn't find similar in some major libraries.
How to define it? or already defined in libs?
data ABC a = A a | B a | C a
f1 = someHigherOrderFunc $ partialMaybe \(A a) -> someFunc a -- if not 'A', return Nothing.
-- same as
f2 = someHigherOrderFunc $ case _ of A a -> Just $ someFunc a
_ -> Nothing -- requires line break, seems syntax redundant...
using: purescript 0.11.6
Edit:
I did it...
partialMaybe :: forall a b. (Partial => a -> b) -> a -> Maybe b
partialMaybe f a = runPure $ catchException (const $ pure Nothing) (Just <<< unsafePartial f <$> pure a)
this is...umm...very ugly. it's not.
'Failed pattern match' exception is thrown by the purescript.
so I think it should be able to handle by purescript.
Can't do it?
If you want an exception if a case is missed, use Partial. If you want otherwise, use Maybe or Either or another appropriate sum type.
You can catch the exception thrown from a failed pattern match. There is no way for a failed pattern match to not throw an exception.
Without using case expressions (that comes in the next section of the class), I can't see why the following doesn't do a quicksort. It goes into a loop somewhere and never ends.
splitAt and append have already been thorughly tested, but here are the codes for them.
fun append(xs, ys) =
if null xs
then ys
else (hd xs) :: append(tl xs, ys)
fun splitAt(xs : int list, x : int) =
let
fun sp(ys : int list, more : int list, less : int list) =
if null ys
then (more, less)
else
if hd ys < x
then sp(tl ys, more, append(less, [hd ys]))
else sp(tl ys, append(more, [hd ys]), less)
in
sp(xs, [], [])
end
fun qsort(xs : int list) =
if length xs <= 1
then xs
else
let
val s = splitAt(xs, hd xs)
in
qsort(append(#2 s, #1 s))
end
And I get the same problem using append(qsort(#2 s), qsort(#1 s)), but I though the former was better style since it only require a single recursion with each round.
I guess I should say that 'splitAt' divides the list into greater than or equal to the second argument, and less than, and creates a tuple). Append concatenates 2 lists.
PS: This is only a practice problem, not a test or homework.
It goes into a loop somewhere and never ends.
Your problem is most likely qsort being called on a list that does not reduce in size upon recursive call. Perhaps go with append(qsort (#2 s), qsort (#1 s)). But even then, can you be sure that each of #1 s and #2 s will always reduce in size?
Ideally you should supply splitAt and append since they're not library functions. You might consider using the built-in append called # and the built-in List.partition to form splitAt.
Compare against this one found somewhere on the interwebs:
fun quicksort [] = []
| quicksort (x::xs) =
let
val (left, right) = List.partition (fn y => y < x) xs
in
quicksort left # [x] # quicksort right
end
Since this isn't homework ...
Note that if xs = [1,2] then splitAt(xs hd xs) returns ([1,2],[]) so the attempt to sort [1,2] by this version of qsort reduces to ... sorting [1,2] again. That will never terminate.
Instead, I would advocate applying splitAt to the tail of the xs. A minimal tweak to your code is to leave append and splitAt alone but to rewrite qsort as:
fun qsort(xs : int list) =
if length xs <= 1
then xs
else
let
val s = splitAt(tl xs, hd xs)
in
append(qsort(#2 s), (hd xs) :: qsort(#1 s))
end;
Then, for example,
- qsort [4,2,1,2,3,6,4,7];
val it = [1,2,2,3,4,4,6,7] : int list
It is crucial that you apply qsort twice then append the results. Tryng to apply qsort once to the appended split would be trying to reduce qsort to applying qsort to a list which is the same size as the original list.
SML really becomes fun when you get to pattern matching. You should enjoy the next chapter.
Is there a concise, idiomatic way how to express function iteration? That is, given a number n and a function f :: a -> a, I'd like to express \x -> f(...(f(x))...) where f is applied n-times.
Of course, I could make my own, recursive function for that, but I'd be interested if there is a way to express it shortly using existing tools or libraries.
So far, I have these ideas:
\n f x -> foldr (const f) x [1..n]
\n -> appEndo . mconcat . replicate n . Endo
but they all use intermediate lists, and aren't very concise.
The shortest one I found so far uses semigroups:
\n f -> appEndo . times1p (n - 1) . Endo,
but it works only for positive numbers (not for 0).
Primarily I'm focused on solutions in Haskell, but I'd be also interested in Scala solutions or even other functional languages.
Because Haskell is influenced by mathematics so much, the definition from the Wikipedia page you've linked to almost directly translates to the language.
Just check this out:
Now in Haskell:
iterateF 0 _ = id
iterateF n f = f . iterateF (n - 1) f
Pretty neat, huh?
So what is this? It's a typical recursion pattern. And how do Haskellers usually treat that? We treat that with folds! So after refactoring we end up with the following translation:
iterateF :: Int -> (a -> a) -> (a -> a)
iterateF n f = foldr (.) id (replicate n f)
or point-free, if you prefer:
iterateF :: Int -> (a -> a) -> (a -> a)
iterateF n = foldr (.) id . replicate n
As you see, there is no notion of the subject function's arguments both in the Wikipedia definition and in the solutions presented here. It is a function on another function, i.e. the subject function is being treated as a value. This is a higher level approach to a problem than implementation involving arguments of the subject function.
Now, concerning your worries about the intermediate lists. From the source code perspective this solution turns out to be very similar to a Scala solution posted by #jmcejuela, but there's a key difference that GHC optimizer throws away the intermediate list entirely, turning the function into a simple recursive loop over the subject function. I don't think it could be optimized any better.
To comfortably inspect the intermediate compiler results for yourself, I recommend to use ghc-core.
In Scala:
Function chain Seq.fill(n)(f)
See scaladoc for Function. Lazy version: Function chain Stream.fill(n)(f)
Although this is not as concise as jmcejuela's answer (which I prefer), there is another way in scala to express such a function without the Function module. It also works when n = 0.
def iterate[T](f: T=>T, n: Int) = (x: T) => (1 to n).foldLeft(x)((res, n) => f(res))
To overcome the creation of a list, one can use explicit recursion, which in reverse requires more static typing.
def iterate[T](f: T=>T, n: Int): T=>T = (x: T) => (if(n == 0) x else iterate(f, n-1)(f(x)))
There is an equivalent solution using pattern matching like the solution in Haskell:
def iterate[T](f: T=>T, n: Int): T=>T = (x: T) => n match {
case 0 => x
case _ => iterate(f, n-1)(f(x))
}
Finally, I prefer the short way of writing it in Caml, where there is no need to define the types of the variables at all.
let iterate f n x = match n with 0->x | n->iterate f (n-1) x;;
let f5 = iterate f 5 in ...
I like pigworker's/tauli's ideas the best, but since they only gave it as a comments, I'm making a CW answer out of it.
\n f x -> iterate f x !! n
or
\n f -> (!! n) . iterate f
perhaps even:
\n -> ((!! n) .) . iterate
I know that Haskell's
do
x <- [1, 2, 3]
y <- [7, 8, 9]
let z = (x + y)
return z
can be expressed in Scala as
for {
x <- List(1, 2, 3)
y <- List(7, 8, 9)
z = x + y
} yield z
But, especially with monads, Haskell often has statements inside the do block that don't correspond to either <- or =. For example, here's some code from Pandoc that uses Parsec to parse something from a string.
-- | Parse contents of 'str' using 'parser' and return result.
parseFromString :: GenParser tok st a -> [tok] -> GenParser tok st a
parseFromString parser str = do
oldPos <- getPosition
oldInput <- getInput
setInput str
result <- parser
setInput oldInput
setPosition oldPos
return result
As you can see, it saves the position and input, runs the parser on the string, and then restores the input and position before returning the result.
I can't for the life of me figure out how to translate setInput str, setInput oldInput, and setPosition oldPos into Scala. I think it would work if I just put nonsense variables in so I could use <-, like
for {
oldPos <- getPosition
oldInput <- getInput
whyAmIHere <- setInput str
result <- parser
...
} yield result
but I'm not sure that's the case and, if it is correct, I'm sure that there must be a better way to do this.
Oh, and if you can answer this question, can you answer one more: how long do I have to stare at Monads before they don't feel like black magic? :-)
Thanks!
Todd
Yes, that translation is valid.
do { x <- m; n } is equivalent to m >>= \x -> n, and do { m; n } is equivalent to m >> n. Since m >> n is defined as m >>= \_ -> n (where _ means "don't bind this value to anything"), that is indeed a valid translation; do { m; n } is the same as do { _ <- m; n }, or do { unusedVariable <- m; n }.
A statement without a variable binding in a do block simply disregards the result, usually because there's no meaningful result to speak of. For instance, there's nothing interesting to do with the result of putStrLn "Hello, world!", so you wouldn't bind its result to a variable.
(As for monads being black magic, the best realisation you can have is that they're not really complicated at all; trying to find deeper meaning in them is not generally a productive way of learning how they work. They're simply an interface to compose computations that happen to be particularly common. I recommend reading the Typeclassopedia to get a solid grasp on Haskell's abstract typeclasses, though you'll need to have read a general Haskell introduction to get much out of it.)
I have been looking into recursion and TCO. It seems that TCO can make the code verbose and also impact the performance. e.g. I have implemented the code which takes in 7 digit phone number and gives back all possible permutation of words e.g. 464-7328 can be "GMGPDAS ... IMGREAT ... IOIRFCU" Here is the code.
/*Generate the alphabet table*/
val alphabet = (for (ch <- 'a' to 'z') yield ch.toString).toList
/*Given the number, return the possible alphabet List of String(Instead of Char for convenience)*/
def getChars(num : Int) : List[String] = {
if (num > 1) return List[String](alphabet((num - 2) * 3), alphabet((num - 2) * 3 + 1), alphabet((num - 2) * 3 + 2))
List[String](num.toString)
}
/*Recursion without TCO*/
def getTelWords(input : List[Int]) : List[String] = {
if (input.length == 1) return getChars(input.head)
getChars(input.head).foldLeft(List[String]()) {
(l, ch) => getTelWords(input.tail).foldLeft(List[String]()) { (ll, x) => ch + x :: ll } ++ l
}
}
It is short and I don't have to spend too much time on this. However when I try to do that in tail call recursion to get it TCO'ed. I have to spend a considerable amount of time and The code become very verbose. I won't be posing the whole code to save space. Here is a link to git repo link. It is for sure that quite a lot of you can write better and concise tail recursive code than mine. I still believe that in general TCO is more verbose (e.g. Factorial and Fibonacci tail call recursion has extra parameter, accumulator.) Yet, TCO is needed to prevent the stack overflow. I would like to know how you would approach TCO and recursion. The Scheme implementation of Akermann with TCO in this thread epitomize my problem statement.
Is it possible that you're using the term "tail call optimization", when in fact you really either mean writing a function in iterative recursive style, or continuation passing style, so that all the recursive calls are tail calls?
Implementing TCO is the job of a language implementer; one paper that talks about how it can be done efficiently is the classic Lambda: the Ultimate GOTO paper.
Tail call optimization is something that your language's evaluator will do for you. Your question, on the other hand, sounds like you are asking how to express functions in a particular style so that the program's shape allows your evaluator to perform tail call optimization.
As sclv mentioned in the comments, tail recursion is pointless for this example in Haskell. A simple implementation of your problem can be written succinctly and efficiently using the list monad.
import Data.Char
getChars n | n > 1 = [chr (ord 'a' + 3*(n-2)+i) | i <- [0..2]]
| otherwise = ""
getTelNum = mapM getChars
As said by others, I would not be worried about tail call for this case, as it does not recurse very deeply (length of the input) compared to the size of the output. You should be out of memory (or patience) before you are out of stack
I would implement probably implement with something like
def getTelWords(input: List[Int]): List[String] = input match {
case Nil => List("")
case x :: xs => {
val heads = getChars(x)
val tails = getTelWords(xs)
for(c <- heads; cs <- tails) yield c + cs
}
}
If you insist on a tail recursive one, that might be based on
def helper(reversedPrefixes: List[String], input: List[Int]): List[String]
= input match {
case Nil => reversedPrefixes.map(_.reverse)
case (x :: xs) => helper(
for(c <- getChars(x); rp <- reversedPrefixes) yield c + rp,
xs)
}
(the actual routine should call helper(List(""), input))