Search code examples
haskellclojurecode-translation

Haskell Function to Clojure function conversion


Trying to convert Haskell function to Clojure. But facing difficulties. Not sure what's happening.

Here's recursive Haskell function.

  mapWidth :: [[Char]] -> Int
  mapWidth [] = 0
  mapWidth (x:xs)
  | length xs == 0 = length x
  | length x /= length (xs!!0) = -1
  | otherwise = mapWidth(xs)

Here's what I've tried so far :

(defn mapWidth [data_list]
    (def data 0)
    ([[x & xs](seq data_list)](if (= (count x) 0) 
    (data 0)
    (data -1))))
    ([[x & xs](seq data_list)](if not(= (count xs) length (xs!!0))
    (data 0)
    (data -1)
    mapWidth(xs)))

Any help is appreciated. I'm pretty new to both the languages.


Solution

  • as far as i can see, this function returns length of an element, if all elements have the equal length. In this case it could look like this:

    (defn map-len [[x & [y :as xs]]]
      (cond (empty? xs) (count x)
            (not= (count x) (count y)) -1
            :else (recur xs)))
    

    which is almost the exact rewrite of haskell variant (replacing straight recursive call with recur)

    (map-len [[1 2] [3 4] [5 6]])
    ;;=> 2
    
    (map-len [[1 2] [3 4 5] [5 6]])
    ;;=> -1
    

    bot since clojure is about operations on sequences, you can do it in a more idiomatic way (as for me, it is):

    (defn map-len2 [data]
      (cond (empty? data) 0
            (apply = (map count data)) (count (first data))
            :else -1))
    
    (defn map-len3 [[x & xs]]
      (let [c (count x)]
        (if (every? #(= c (count %)) xs)
          c
          -1)))