¿Hay alguna manera de ver los pasos de reducción en haskell, es decir, rastrear las llamadas a la función recursiva realizadas? Por ejemplo, el esquema Chez nos proporciona trace-lambda. ¿Hay una forma equivalente en Haskell?Ver Pasos de reducción en Haskell
Respuesta
Puede intentar insertar Debug.Trace.trace
en los lugares que desea rastrear, pero esto tiene la tendencia de (a) producir resultados descabellados fuera de orden, ya que su instrucción de rastreo puede pertenecer a un procesador que no se evalúa hasta ahora muy lejos de la llamada original, y (b) cambiando el comportamiento del tiempo de ejecución de su programa, si el rastreo requiere evaluar cosas que de otro modo no se hubieran evaluado (aún).
¿Esto es para la depuración? Si es así ...
Hat modifica el código fuente para el rastreo de salida que se puede ver después de correr. La salida debe ser bastante cerca de lo que quiere: el ejemplo en su página web es
Por ejemplo, el cálculo del programa defectuoso
main = let xs :: [Int] xs = [4*2,5 `div` 0,5+6] in print (head xs,last' xs) last' (x:xs) = last' xs last' [x] = x
da el resultado
(8, No match in pattern.
y las herramientas del sombrero de visualización se pueden utilizar para explorar su comportamiento de la siguiente manera:
- Hat-pila
para cálculos abortados, es decir cálculos que termina con un mensaje de error o interrumpidas, hat-pila muestra en la que la función de llamada el cálculo fue abortado. Lo hace al mostrar una pila virtual de llamadas a función (redexas). Por lo tanto, cada llamada de función que se muestra en la pila provocó la llamada a la función que está sobre ella. La evaluación del elemento de pila superior provocó el error (o durante su evaluación se interrumpió el cálculo). La pila que se muestra es virtual, porque no se corresponde con la pila de tiempo de ejecución real. La pila de tiempo de ejecución real permite la evaluación diferida, mientras que la pila virtual corresponde a una pila que se usaría para una evaluación (estricta) ansiosa.
Usando el mismo programa de ejemplo que el anterior, hat-pila muestra
$ hat-stack Example Program terminated with error: No match in pattern. Virtual stack trace: (Last.hs:6) last' [] (Last.hs:6) last' [_] (Last.hs:6) last' [_,_] (Last.hs:4) last' [8,_,_] (unknown) main $
Estos días, GHCi (≥ 6.8.1) también viene con un depurador:
$ ghci -fbreak-on-exception
GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> :l Example.hs
[1 of 1] Compiling Main (Example.hs, interpreted)
Example.hs:5:0:
Warning: Pattern match(es) are overlapped
In the definition of `last'': last' [x] = ...
Ok, modules loaded: Main.
*Main> :trace main
(8,Stopped at <exception thrown>
_exception :: e = _
[<exception thrown>] *Main> :back
Logged breakpoint at Example.hs:(5,0)-(6,12)
_result :: t
[-1: Example.hs:(5,0)-(6,12)] *Main> :hist
-1 : last' (Example.hs:(5,0)-(6,12))
-2 : last' (Example.hs:5:15-22)
-3 : last' (Example.hs:(5,0)-(6,12))
-4 : last' (Example.hs:5:15-22)
-5 : last' (Example.hs:(5,0)-(6,12))
-6 : last' (Example.hs:5:15-22)
-7 : last' (Example.hs:(5,0)-(6,12))
-8 : main (Example.hs:3:25-32)
-9 : main (Example.hs:2:17-19)
-10 : main (Example.hs:2:16-34)
-11 : main (Example.hs:3:17-23)
-12 : main (Example.hs:3:10-33)
<end of history>
[-1: Example.hs:(5,0)-(6,12)] *Main> :force _result
*** Exception: Example.hs:(5,0)-(6,12): Non-exhaustive patterns in function last'
[-1: Example.hs:(5,0)-(6,12)] *Main> :back
Logged breakpoint at Example.hs:5:15-22
_result :: t
xs :: [t]
[-2: Example.hs:5:15-22] *Main> :force xs
xs = []
Aunque no es tan agradable, tiene la ventaja de estar fácilmente disponible y ser utilizable sin volver a compilar el código.
¿Hay una reducción en los abrazos, si eso ayuda? Como alternativa, ¿podría usar algo como la capucha de abrazos para envolver su código, para obtener más detalles sobre lo que está haciendo en cada paso?
Nada del tipo está integrado en el estándar Haskell.
Espero que el intérprete gráfico Helium ofrezca algo como esto, pero la página web no menciona el tema.
Una solución parcial es usar vacuum para visualizar estructuras de datos.
He visto algunas animaciones gif de doblar, escanear y otras, pero no las puedo encontrar en este momento. Creo que Cale Gibbard hizo las animaciones.
- 1. Función predecesora de cálculo lambda pasos de reducción
- 2. ¿Cómo escribo una reducción paralela usando estrategias en Haskell?
- 3. Reducción en la perspectiva
- 4. Analizador de reducción en Javascript
- 5. remquo: reducción de argumento?
- 6. oblicua detección y reducción en opencv
- 7. Reducción de imágenes en lugar de Estirar
- 8. Visualización de fórmula de reducción en GitHub
- 9. ¿Algoritmo de reducción de cola?
- 10. reducción segmentada con segmentos dispersos
- 11. Reutilizar Pasos de pepino
- 12. Reducción de llamadas parse en Oracle
- 13. Reducción del tamaño de bitmap en C#
- 14. Reducción a PDF
- 15. ¿Qué significa reducción de dimensionalidad?
- 16. Reducción de resolución sin suavizado
- 17. Reducción del tamaño de JRE
- 18. Android: Detener la reducción de la imagen
- 19. ¿Se refactoriza en pequeños pasos?
- 20. Pasos en la subclase UINavigationController
- 21. Implementador de interconexión de pasos/depuración
- 22. Crear registro de varios pasos en iOS
- 23. Autenticación de 2 pasos en ASP.Net MVC
- 24. Saltando pasos en el trabajo de Jenkins
- 25. ¿Reducción a texto sin formato en Ruby?
- 26. revertir pasos error multihilo
- 27. Pasos para instalar py2cairo?
- 28. Reducción de miles de advertencias de compilación
- 29. Primeros pasos con ColdFusion?
- 30. Primeros pasos con autotools
Hay una gran diferencia con Scheme; Haskell es flojo, por lo que la evaluación real puede ocurrir mucho después de la llamada. – bortzmeyer