Split Function - cannot construct the infinite type

Kevin Meredith

The following code fails to compile:

split :: Char -> String -> [String]
split x ys = split' x ys [] 
              where split' _  [] acc = acc
                    split' x (z:zs) acc  
                     | x == z    = acc : split' x zs []
                     | otherwise = split' x zs (z:acc)  

Compile-time error:

[1 of 1] Compiling Main             ( Split.hs, interpreted )

Split.hs:5:36:
    Occurs check: cannot construct the infinite type: a0 = [a0]
    In the first argument of `(:)', namely `acc'
    In the expression: acc : split' x zs []
    In an equation for split':
        split' x (z : zs) acc
          | x == z = acc : split' x zs []
          | otherwise = split' x zs (z : acc)
Failed, modules loaded: none.

I read through this helpful post, but I'm not seeing my mistake.

chi

The posted code defined split' returning acc in one case and acc : <<something>> in another case. The compiler message states that, if a0 is the type of acc, since both cases must return the same type it should be a0 = [a0]. Since no type can satisfy this equation (e.g. String is not [String]), the compiler complains with a type error.

A fix could then be to return a list containing acc is both cases. That is:

split :: Char -> String -> [String]
split x ys = split' x ys [] 
              where split' _  [] acc = [acc]             -- changed
                    split' x (z:zs) acc  
                     | x == z    = acc : split' x zs []
                     | otherwise = split' x zs (z:acc)

As a style note, since x is kept the same in each recursive call, there is no actual need for that parameter.

split :: Char -> String -> [String]
split x ys = split' ys [] 
              where split' [] acc = [acc]
                    split' (z:zs) acc  
                     | x == z    = acc : split' zs []
                     | otherwise = split' zs (z:acc)

The code is now type safe, but it still contains a bug:

> split 'a' "123a1234a"
["321","4321",""]

This is because the code "pops" characters from the string and "pushes" them in acc, so they end up being reversed. The fix is then easy:

split :: Char -> String -> [String]
split x ys = split' ys [] 
              where split' :: String -> String -> [String]
                    split' [] acc = [reverse acc]
                    split' (z:zs) acc  
                     | x == z    = reverse acc : split' zs []
                     | otherwise = split' zs (z:acc)

In this last revision I also added a type signature for the worker function, to document its code.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Java scoping construct cannot be annotated with type-use

Cannot construct a collection of type ...Inclusive[Long] with elements of type Long based on a collection of type ...Inclusive[Long]

VBA type mismatch in split function

Error on defining Applicative's <*> with record accessors: cannot construct the infinite type: t ~ t -> t1

Cannot construct inifnite type

How do I construct a type that describes a mutation made on a function parameter?

cannot construct the infinite type when using foldl

Haskell: cannot construct the infinite type

Haskell - cannot construct the infinite type

How to define a type: infinite function?

Haskell Newbie - Occurs check: cannot construct the infinite type: a ~ [a]

SQL: "Cannot construct data type date" when comparing two dates

Doobie cannot find or construct a Read instance for type T

Struggling to understand a "Cannot construct the infinite type" error

Cannot deduce function return type

Haskell foldl cannot construct the infinite type

Compile error: Occurs check: cannot construct the infinite type: a1 = [a1]

How can I deal with "Occurs check: cannot construct the infinite type: a0 = [a0]"?

"infinite type" error in haskell, cannot find whats wrong

haskell fibonacci - cannot construct the infinite type: a0 = [a0]

Cannot invoke $function with object of type *

passing function to function generate infinite type

Construct a type

cannot construct the infinite type: e ~ [e]

Recursion in conditional definition in Haskell gives error ( Occurs check: cannot construct the infinite type:)

Cannot invoke split(String) on the array type String[]

Cannot construct infinite type with functor

Why do I get this "cannot construct the infinite type: a ~ [a]" error in Haskell?

Cannot find or construct a Read instance for type: Option[A]