Skip to content

erolm-a/haskell-lvalue

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

haskell-lvalue: Bring C-style lvalues to haskell!

Rationale

Recently I stumbled across a nice overview on how we can embed a C-style programming language with lvalues in haskell, and wondered why did no-one write a library for that?. And here I am.

Mind, this library is at the current stage a bit more than a hack. While it tries to make working with IORefs (the Haskell equivalent of imperative languages stateful variables) a lot easier, it should not be used as a replacement for functional programming.

This library attempts to implement with the means of General Algebraic Data Types a type-safe version of lvalues. Your code won't compile if you try to use them wrong ¹.

Usage

To make it C-like, the module exports lvalues and rvalues on basic data types (basically wrapping IORefs) and a nice C-like syntax for 1-D arrays.

Some operators have been defined but are meant to be used like the C ones (e.g. >, >=, ||, && etc.) and thus can clash with the prelude. Please import them qualified, or hide some Prelude functions.

That said, let's look at how to use it:

new, copy, assignment (=:) and constant

{-# LANGUAGE NoImplicitPrelude#-}

import LValue

main = do
    x <- new 3
    y <- copy x
    y =: x * y
    runExpression y >>= \val -> putStrLn "Now y contains" ++ show val

    -- (x + y) =: new 42 -- Error: rvalues are not assignable
    let z = constant 42
    x += z
    y += z
    -- z += z -- Error: constants are rvalues, thus not assignable
    runExpression y >>= \val -> putStrLn "Now y contains" ++ show val

Expected output:

Now y contains 9
Now y contains 51

Internally, x, y, z are instances of Expr' v a. v is a phantom type used to make conversions between lvalues and rvalues possible in only one way.

The function runExpression takes an expression in the form Expr' v a and returns an IO a containing the value.

How do new, copy and constant differ? Simple:

  • new generates a new lvalue given a naked value
  • copy copies an existing *value and copies it into a new lvalue
  • constant generates a new rvalue given a naked value. It does not create a new IORef internally and can be conceptually seen as a C-style const (i.e. not modifiable, not necessarily a constant literal).

TODO

  • Add an example for arrays
  • Implement while loops
  • Implement for loops
  • Make some IO wrappers
  • Make it work outside the IO monad (e.g. ST monad)
  • Possibly integrate Template Haskell

Notes

¹: At this stage, some operations rely on runtime checks, for example array indexing requires the lists to only have one element.

About

Type-safe C-Style lvalues in Haskell

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published