# Tag Info

10

When you have a function where not every possible input value can be mapped to one of the possible output values, you have three options: Allow fewer inputs, allow more outputs, or declare that your function is partial rather than total and just isn't well-behaved sometimes. The first is arguably the most flexible, but often involves some awkward re-shaping ...

5

This looks fine. Every top-level binding has a type signature, and all functions are nice and short. However, the mergeLines and mergeSquares functions could use a little bit more documentation. There is also (probably) an algorithm that doesn't introduce that many lines just to throw them away in mergeLines. Other than that, there are three possible ...

5

Food for thought: From my (now deleted) comment: Your operators are associative, but your data structure is not. Is there a different data representation which is associative? I think you want to do more with this tree than just printing it, right? The problem is you want Q Unit (Q Unit Unit) to be equal to Q (Q Unit Unit) Unit. Find a 'canonical' ...

5

I'm a little out of practice with haskell, but I'm quite fond of it. I want to address your "extra" question first. wich one of the 2 version is more readable for an haskell programmer, and why ? [sic] Haskell programmers aren't a special magic kind of people. They tend to take the benefits of brevity more seriously than folks in love with python,...

5

To address your title question ("Is it wrong..."), no, I wouldn't say that it's wrong. Using more top-level functions is nearly always a great way to decompose your problem into smaller, easier to digest bits that are simpler to solve. That said the split that you chose to make doesn't meet that goal. Your functions are tightly coupled in that ...

4

break and span When we try to split a string in Haskell, we're a little bit out of luck if we only use the trusty Prelude and base. Handy functions like split or splitOn are in the adaptly named split package, and parser combinators are completely other beasts and an oribtal (heh) laser cannon on this problem. However, there are two functions that provide ...

4

On my machine, your original Haskell version run on two copies of the "sa3_10000" test file takes about 20 seconds, while your Go version takes about 2 seconds. Note that profiled GHC binaries run significantly slower, even if you don't generate a profile, so you'll want to make sure you're timing an unprofiled binary when making these comparisons....

3

I'd contend that State is pure and functional, but I think translating your current code to use State is an excellent exercise so I'll leave that up to you. The first thing I'd address is making your types do more of the bookkeeping. Well designed types lend themselves to correct-by-construction solutions. data Player = P1 | P2 deriving Show data Game = ...

3

This is very good! The other answer addresses the non-obvious algorithmic improvement, so I'll try to tackle matters of style and hopefully point you toward more FP intuition. Since your Player type isn't fancy, just let the compiler derive your instances. data Player = Player1 | Player2 deriving Eq You will probably also benefit from compiling with ...

3

All the indexing can be deleted. You only need the transpose function plus a custom function that grabs the diagonals of a matrix (list of lists, all of the same length). import Data.List (transpose) -- | The 'diagonals' function returns the diagonals of a matrix diagonals :: [[a]] -> [[a]] diagonals matrix = lowerDiags matrix ++ upperDiags matrix ...

3

It's hard to tell if the compiler would be able to eliminate duplicate calls to delta. It may do that, by inlining the x1 and x2 functions and then eliminating common subexpressions. Personally though, I prefer to do this myself. The following modification is guaranteed to call delta only once: solve (Quadratic a b c) = solutions where both = [x1,...

3

Is it bad to have splitInternal function? I couldn't figure out a way without it. Well, according to your procedure, I think it is necessary, but you can improve the readibility by writing some small functions and then combining them together. Besides, if there are consecutive delimiters, your split function doesn't work as expected. The code can be ...

3

What I'd like to improve on this code is two things: Reduce the lens piping. I could, of course, get rid of _1, _2 and _3 by using a bespoke record type, but then that introduces its own noise -- sim is the only function that uses this particular combination of I, S and O. Is this really a problem? I don't understand what could be improved about that part. ...

3

Just a few ideas - successfully compiled, not tested further. Using record syntax yields the functions suit, rank for "free", i.e. data Card = Card { suit :: Suit , rank :: Rank } allows for shorter definitions: instance Eq Card where c1 == c2 = rank c1 == rank c2 instance Ord Card where c1 compare c2 = rank c1 ...

3

There's no need to use a struct compose_t to wrap operator(), you can just move operator() out of it and rename it compose(): template <typename F, typename G> constexpr decltype(auto) compose(F&& f, G&& g) noexcept { return [&f,&g](auto&& x){ return f(g(std::forward<decltype(x)>(x))); }; } Now it ...

3

I'm not a Haskell programmer, but let me just point out a few things here. First, expressions such as (n-10^i*(ndiv`(10^i))) look quite cluttered. One thing you can do is just put a space between each operator and its operands, and with longer expressions, you can extract pieces and bind them to names to make it easier to understand what's going on. For ...

2

What you're essentially doing with your binary tree is checking all possible combinations of numbers from the list [i^n | i <- [1..x]]. That's quite a lot of combinations! (Exercise: how many?) Not all of those combinations are sensible, however. For example, if x = 100 and n = 2, and you've already chosen, say, 4 and 5 (giving 62+72=85), then adding 82=...

2

countOrbits Let's take a look at what your algorithm is doing. Suppose you are at a root node r with subtree s at depth d0. You return the sum of d0 and all of the depths of the nodes in s. Nitpicks sum [] = 0, so you could just write countOrbitsImpl as its otherwise clause. Not checking the length also makes your code slightly faster. length is O(n) in the ...

2

I think this recursive solution is one pass: :{ isPalindrome inp = if length inp < 2 then True else (if (head inp) /= (last inp) then False else isPalindrome $init$ tail inp) :} Also, it stops as soon as it found it's not a palindrome (if two opposite characters are not identical). It checks the first and last element are equal, then it ...

2

Placing the recursion in show and adding the operator character as an extra parameter simplifies the helper function. data Tree = Unit | E Tree Tree | Q Tree Tree instance Show Tree where show Unit = "1" show (E a@(Q _ _) b) = showExp "!" (surround (show a)) (show b) show (E a b@(Q _ _)) = showExp "!" (show a) (surround (...

2

Short Answer This looks like a decent attempt. There are a few minor stylistic issues, but I think the biggest conceptual problem is a bad choice of Parser type. You should separate ErrorMessage from Leftovers, as these aren't the same sort of thing and so shouldn't share a single field in the algebraic type. Much clearer is: type Parser a = String -> ...

2

A simple rule of thumb is that you should never use readS_to_Prec and readS_to_P. Consider that once you've converted a parser to a ReadS to run it, there is no way back. (One handwavy explanation is that those functions are really dirty hacks, which is also why gather is undefined when they are used.) Under those constraints, the only place where you can ...

2

It's unusual to partially apply infix functions by first prefixing them, (*) 2 is equivalent to (2 *) and the latter is so much more common I can't recall ever even seeing the former. Note that you can also partially apply the second argument, as in (/ 2). When you're using -By functions, a handy tool to have in your toolbox is the higher order function Data....

2

Looks good, matrix operations have been kind of a sore spot for Haskell, but this is example is easy to follow along. I would definitely do is get rid of all the calls to error. Instead, you can wrap a lot of things with Either SomeFailure <Success>, where SomeFailure could just be a string to describe how things failed. Then, you could run your ...

2

First things first: great work on adding a type signature on every function. Now, let's see how we can improve the code. Use interesting case first, others later When we pattern match in a binding or in a case expression, it's often easier to start with the interesting case first and then handle the Error cases: decodeTeacher :: PersonDecoder decodeTeacher ...

2

I would use an interleave helper: interleave :: [a] -> [a] -> [a] interleave (x:xs) ys = x : interleave ys xs binaryRule :: [Integer] binaryRule = interleave [0,0..] (map (+ 1) binaryRule) Or golfed: let(a:b)#c=a:c#b;a=[0,0..]#map(+1)a in a

2

I wouldn't worry about using mutability here. Sometimes it pays to just be straightforward and stick closely to something that you know works. You're not using ScopedTypeVariables. As far as the interface, Costs has no reason to be a data type. It is clearer from the user's perspective to say simply type Costs a = Operation a -> Int -- replacements for ...

2

I think your use of do notation in the splitWord function is bad and I think your code is even correct by accident. Let me add parentheses to highlight it: splitWord s = do let rest = splitWord (tail s) let first = (head s) : (head rest) (return first) ++ tail rest Most people, including me, will assume the last return statement in a do ...

2

You can use scans to implement this: import Data.List peak :: [Int] -> Maybe Int peak [] = Nothing peak xs = elemIndex True \$ zipWith (==) (scanl1 (+) xs) (scanr1 (+) xs) I don't think there is a way to reduce the number of arguments, but I think you can give them shorter names in the helper function and if you put the helper function in a where clause ...

2

Interestingly enough, this can be solved with no math at all. The things to know are: show turns an Int into a String A String is internally actually [Char], so you can map to and from strings as you would lists. read converts a String to the datatype it represents (but does not work with Chars) Putting those together, the steps to turn an integer into a ...

Only top voted, non community-wiki answers of a minimum length are eligible