Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basic result type and functions #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
_build
_checkouts
.rebar3
rebar3.crashdump
rebar.lock
54 changes: 54 additions & 0 deletions src/result.alp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{- Basic result type.
-}
module result

import_type option.option

export isOk/1, map/1, fromOption/2, andThen/2, withDefault/2

export_type result

type result 'a 'b = Ok 'a | Err 'b

let isOk r =
match r with
Ok _ -> true
| Err _ -> false

test "Applying `isOk` to Ok x should return true" =
assert.equal (true) (isOk (Ok 1))

let map f (Ok x) = Ok (f x)

let map _ (Err x) = Err x

test "mapping the identity function to Ok x should return Ok x" =
let f x = x in
assert.equal (Ok 1) (map f (Ok 1))

let fromOption opt e =
match opt with
Some x -> Ok x
| None -> Err e

let andThen callback (Ok value) = callback value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we are using camelCase while everywhere else we are using snake_case. Could we be consistent?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we decided which case we prefer? I'm leaning towards camelCase.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc @lepoetemaudit and I discussed this mid-way through last year and settled on moving to camelCase. I'm easy either way tbh. Other opinions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fab, I'll update the other modules/PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For option this is called flatMap. Which name do we prefer? I took flatMap from Scala as we had option which felt Scala-y to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer andThen personally, but would also change it in option, hehe. So if it is staying that way in option then to be consistent I'll change it here.

Maybe in scala the option and result types are actually related to sequences and so a flatMap makes sense? To me it doesn't fit in the alpaca case and would be confusing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the result of composing flatten : m m a -> m a and map, so I think it makes sense.

I find the name andThen a little odd, doesn't seem to fit with map, fold etc

let andThen _ (Err msg) = Err msg

test "andThen test with Ok x" =
let f x = (Ok x) in
assert.equal (Ok 1) (andThen f (Ok 1))

test "andThen with Err x and identity function is Err x" =
let f x = (Ok x) in
assert.equal (Err "msg") (andThen f (Err "msg"))

let withDefault _ (Ok x) = x
let withDefault default (Err _) = default

test "withdefault test with Ok result" =
let f x = (Ok x) in
assert.equal (1) (withDefault 0 (f 1))

test "withdefault test with Err returning default" =
let f _ = (Err "error") in
assert.equal (0) (withDefault 0 (f 1))