rubyhs/doc/presentation.org
2019-10-11 16:55:48 +02:00

1.6 KiB
Raw Blame History

Introduction

Write a static analyzer for ruby.

Used an existing parser for ruby called `ruby-parse`.

`ruby-parse` can generate an AST in JSON format.

This made the task of writing a ruby parser simpler: Haskell comes with a great JSON parser. So we just have to specify how to convert from the AST defined by `ruby-parse` to our own AST.

Implementation

ADTs

Purpose

Defining an Abstract Syntax Tree (AST) for Ruby using Algebraic Data Types (ADTs).

Example

Value represents any JSON data (object, string, number, null, array) Args = Value Name = Value Block = [Definition] Definition = Module | Function | Send Namespace = [Name] Send = {args : Args, namespace : Namespace, name :: Name} Module = {name : Name, block : Block} Function = {name : Name, args : Args, block :: Block}

Live coding

Define `Function`

Higher-order types

Missing a good example here.

Type classes

Purpose

Be able to concert unstructured JSON data into our ADT.

Example

Consider the class

class FromJSON a where parseJSON :: Value -> Parser a

It's saying that `a` is convertible from json if there is a function `parseJSON` that takes a (json) `Value` and returns a `Parser a`. `Parser a` can be thought of as a procedure for generating a value of type `a`.

So for instance. The monomorphic type `Parser Function` is a procedure that generates a value of type `Function`:

Live coding

Define an instance for `FromJSON` for `Function`.

Define an instance for `FromJSON` for `Definition`.