Number of possible numbers in roman number string
Use pattern matching to check for single-element lists

Let's start with romamCombination's second pattern:

romanCombinations str = if length str == 1 then 1


Compared to Java, length isn't a constant time operation in Haskell. It will traverse the whole list. If we only want to know if a list consists of a single element, we should pattern match to get a constant time behaviour:

romanCombinations [_] = 1


Use named variants of folds where applicable

Next, we will sum all elements in some list:

  -- we have to change the else due to the new pattern, but more on that later
  else foldr (+) 0 [ romanCombinations xs | (x, xs) &lt;- sep , elem x possibles ]


However, foldr (+) 0 is a common operation and therefore has a name in the Prelude: sum. We should use the named variant to convey our intend:

  else sum [ romanCombinations xs | (x, xs) &lt;- sep , elem x possibles ]


Similarly, divide is already in the Prelude, it's called splitAt, although the arguments are flipped:

  where
    divide str n = splitAt n str


Use Hoogle to find functions

But how would we find those functions? With Hoogle. If we search for Num a =&gt; \[a\] -&gt; a, we will come across sum very soon, and if we search for [a] -&gt; Int -&gt; ([a], [a]), Hoogle will also find splitAt, even though the arguments are flipped.

Note that you sometimes need to use more general type signatures to find something with Hoogle.

All together so far

If we apply all those recommendations, we end up with

romanCombinations :: String -&gt; Int
romanCombinations []  = 1
romanCombinations [_] = 1
romanCombinations str = sum [ romanCombinations xs | (x, xs) &lt;- sep , elem x possibles ]
  where
    sep       = map (`splitAt` str) $ take (length str) [1..4]
    possibles = ["X", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]


Adjusting the length of a list by another list

We're already at the end. However, there is one last step we should take: get rid of the other length. That can be done with zip and map:

limit :: [a] -&gt; [b] -&gt; [b]
limit xs = map snd . zip  xs


In case you're not familiar with pointfree-code, it's the same as

limit :: [a] -&gt; [b] -&gt; [b]
limit xs ys = map snd (zip xs ys)


As zip will end whenever the shorter list is exhausted, this will limit str to at most 4 elements in [1..4] and of course limit [1..4] to at most length str.

We end up with

romanCombinations :: String -&gt; Int
romanCombinations []  = 1
romanCombinations [_] = 1
romanCombinations str = sum [ romanCombinations xs | (x, xs) &lt;- sep , elem x possibles ]
  where
    sep       = map (`splitAt` str) $ limit str [1..4]
    possibles = ["X", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]

limit :: [a] -&gt; [b] -&gt; [b]
limit xs = map snd . zip  xs


Bottom line

All in all, your original code was already easy to read, had type signatures and uses   simple splitting algorithm one can easily infer from your code. That being said, I haven't checked your algorithm or thought about improvements but only checked the code.

I recommend you to check the Prelude, as splitAt and sum are already available for your use without any import. Also, try to avoid length. Either work with the list immediately (e.g. map, fold, sum, ...) or pattern match.