2009-12-15 14 views
7

Estoy repasando esta conferencia de Haskell en count down game, no conozco ningún haskell pero estoy interesado en el problema, estoy tratando de portar su código a clojure.Haskell to Clojure

esta es la parte que quedó atascado Debe haber algo que no entiendo en Haskell,


split    :: [a] -> [([a],[a])] 
split []    = [([],[])] 
split (x:xs)   = ([],x:xs) : [(x:ls,rs) | (ls,rs) [([a],[a])] 
nesplit    = filter ne . split 

ne     :: ([a],[b]) -> Bool 
ne (xs,ys)   = not (null xs || null ys) 

exprs    :: [Int] -> [Expr] 
exprs []    = [] 
exprs [n]    = [Val n] 
exprs ns    = [e | (ls,rs)

tengo mi propia división da 1 2 3 4 escupe,

(((1) (2 3 4)) ((1 2) (3 4)) ((1 2 3) (4))) 

(defn split [v] 
    (if (= (count v) 1) 
    (list (first v)) 
    (map #(list (take % v) (drop % v)) (range 1 (count v))))) 

(defn exprs [v] 
    (if (= (count v) 1) 
    v 
    (map #(concat (exprs (first %)) (exprs (second %))) v))) 

(exprs (split [1 2 3 4])) 

que me da,

java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer 

Puede una nyone dime qué me falta del código haskell?

Su lista completa de código está disponible here.

+0

Es la última línea de su código Haskell que falta un cuadrado de cierre ¿soporte? –

+1

Eché un vistazo al mismo problema aquí, aunque con más fuerza bruta que la elegante solución de Graham Hutton. Ver http://www.fatvat.co.uk/2009/02/countdown.html –

+0

muchas gracias Jeff, estaba intentando el método de la fuerza bruta de todos modos. –

Respuesta

4

Esto está siguiendo de cerca la aplicación de Haskell en cuanto a mi limitada fu Haskell me permite hacer ....

(defn split 
    [s] 
    (map #(split-at % s) (range 1 (count s)))) 

(defn ne 
    [s] 
    (every? (complement empty?) s)) 

(defn nesplit 
    [s] 
    (filter ne (split s))) 

(declare combine) 

(defn exprs 
    [s] 
    (when-let [s (seq s)] 
    (if (next s) 
     (for [[ls rs] (nesplit s) 
      l  (exprs ls) 
      r  (exprs rs) 
      e  (combine l r)] 
     e) 
     s)))

no lo he probado sin embargo.

En cuanto a su mensaje de error: Creo que el problema es que no llama split recursivamente en exprs. Entonces obtienes 1 donde se esperaba una secuencia ...

Aleatorio otra nota: count es lineal en el tiempo para las secuencias. Como solo necesitamos saber si tenemos más de un elemento, podemos verificar el valor de (next s) contra nil.

+0

De todos modos: llamamos 'count' en' split' de todos modos. Así que no importa. – kotarak

4

la excepción se deriva de que los exprs se invocan recursivamente y, finalmente, se invocan con una lista de enteros. su código solo maneja una lista de listas o una lista de longitud uno.

(exprs '(2 3 4)) 

lleva a la rama else de la sentencia if que se expande a:

(map #(concat (exprs (first %)) (exprs (second %))) '(2 3 4)))) 

que sale a:

(concat (exprs (first 2)) (exprs (second 2))) 
(concat (exprs (first 3)) (exprs (second 3))) 
(concat (exprs (first 4)) (exprs (second 4))) 

y (primero 2) tiros:

java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer