Idiomatic Haskell RLE in Purescript

So I'm trying to learn Purescript by converting some Haskell code that I had from 99 Haskell Problems , and quickly got into a situation where I know how to solve it, but it's just too ugly. Here's the Haskell code for tasks 10, 11, and 12; basically some RLE encoding and decoding functions:

-- Problem 10

rle :: Eq α => [α] -> [(Int, α)]
rle [] = []
rle (x:xs) = let (h, t) = span (== x) xs 
              in (length h + 1, x) : rle t

-- Problem 11

data RleItem α = Pair Int α | Single α deriving (Show)

encode :: Eq α => [α] -> [RleItem α]
encode = map unpack . rle 
   where unpack (1, x) = Single x
         unpack (y, x) = Pair y x

-- Problem 12

decode :: [RleItem α] -> [α]
decode = concatMap unroll
  where unroll (Pair y x) = replicate y x
        unroll (Single x) = [x] 

I quickly realized that:

  • No reduction [];
  • No tuples (,);
  • We need to quantify explicit polymorphic functions forall;
  • Match patterns with the operator cons (:)for the type Array;
  • ...

So here is the question: what is the most idiomatic way to write the above solution in Purescript?

+4
2

[]

PureScript List

(,)

PureScript Tuple, - , .

forall

cons (:)

List :. , Array, , .

PureScript, , . : http://try.purescript.org/?gist=f45651a7f4d134d466d575b1c4dfb614&backend=core

-- Problem 10

rle :: forall a. (Eq a) => List a -> List {repetitions :: Int, value :: a}
rle Nil = Nil
rle (x:xs) = case span (_ == x) xs of
  {init: h, rest: t} -> {repetitions: length h + 1, value: x} : rle t

-- Problem 11

data RleItem a = Pair Int a | Single a

encode :: forall a. Eq a => List a -> List (RleItem a)
encode = map unpack <<< rle 
   where 
    unpack = case _ of
      {repetitions: 1, value} -> Single value
      {repetitions, value} -> Pair repetitions value

-- Problem 12

decode :: forall a. List (RleItem a) -> List a
decode = concatMap unroll
  where unroll (Pair y x) = replicate y x
        unroll (Single x) = singleton x 
+5

( 1:1), :

data RleItem α = Pair Int α | Single α

encode :: forall α. (Eq α) => List α -> List (RleItem α)
encode Nil = Nil
encode p@(x:_) = let s = span ((==) x) p in
  pack (length s.init) : encode s.rest where
    pack 0 = Single x
    pack y = Pair y x

decode :: forall α. List (RleItem α) -> List α
decode = (=<<) unpack where
  unpack (Single x) = pure x
  unpack (Pair y x) = replicate y x
+1

Source: https://habr.com/ru/post/1671842/


All Articles