-
Notifications
You must be signed in to change notification settings - Fork 381
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
264 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
module Data.List.Lazy | ||
|
||
%default total | ||
|
||
-- All functions here are public export | ||
-- because their definitions are pretty much the specification. | ||
|
||
public export | ||
data LazyList : Type -> Type where | ||
Nil : LazyList a | ||
(::) : (1 x : a) -> (1 xs : Lazy (LazyList a)) -> LazyList a | ||
|
||
public export | ||
Semigroup (LazyList a) where | ||
[] <+> ys = ys | ||
(x :: xs) <+> ys = x :: (xs <+> ys) | ||
|
||
public export | ||
Monoid (LazyList a) where | ||
neutral = [] | ||
|
||
public export | ||
Foldable LazyList where | ||
foldr op nil [] = nil | ||
foldr op nil (x :: xs) = x `op` foldr op nil xs | ||
|
||
foldl op acc [] = acc | ||
foldl op acc (x :: xs) = foldl op (acc `op` x) xs | ||
|
||
public export | ||
Functor LazyList where | ||
map f [] = [] | ||
map f (x :: xs) = f x :: map f xs | ||
|
||
public export | ||
Applicative LazyList where | ||
pure x = [x] | ||
fs <*> vs = concatMap (\f => map f vs) fs | ||
|
||
public export | ||
Alternative LazyList where | ||
empty = [] | ||
(<|>) = (<+>) | ||
|
||
public export | ||
Monad LazyList where | ||
m >>= f = concatMap f m | ||
|
||
-- There is no Traversable instance for lazy lists. | ||
-- The result of a traversal will be a non-lazy list in general | ||
-- (you can't delay the "effect" of an applicative functor). | ||
public export | ||
traverse : Applicative f => (a -> f b) -> LazyList a -> f (List b) | ||
traverse g [] = pure [] | ||
traverse g (x :: xs) = [| g x :: traverse g xs |] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
module Data.String.Iterator | ||
|
||
import public Data.List.Lazy | ||
|
||
%default total | ||
|
||
-- Backend-dependent string iteration type, | ||
-- parameterised by the string that it iterates over. | ||
-- | ||
-- Beware: the index is checked only up to definitional equality. | ||
-- In theory, you could run `decEq` on two strings | ||
-- with the same content but allocated in different memory locations | ||
-- and use the obtained Refl to coerce iterators between them. | ||
-- | ||
-- The strictly correct solution is to make the iterators independent | ||
-- from the exact memory location of the string given to `uncons`. | ||
-- (For example, byte offsets satisfy this requirement.) | ||
export | ||
data StringIterator : String -> Type where [external] | ||
|
||
-- This function is private | ||
-- to avoid subverting the linearity guarantees of withString. | ||
%foreign | ||
"scheme:blodwen-string-iterator-new" | ||
"javascript:stringIterator:new" | ||
private | ||
fromString : (str : String) -> StringIterator str | ||
|
||
-- This function uses a linear string iterator | ||
-- so that backends can use mutating iterators. | ||
export | ||
withString : (str : String) -> ((1 it : StringIterator str) -> a) -> a | ||
withString str f = f (fromString str) | ||
|
||
-- We use a custom data type instead of Maybe (Char, StringIterator) | ||
-- to remove one level of pointer indirection | ||
-- in every iteration of something that's likely to be a hot loop, | ||
-- and to avoid one allocation per character. | ||
-- | ||
-- The Char field of Character is unrestricted for flexibility. | ||
public export | ||
data UnconsResult : String -> Type where | ||
EOF : UnconsResult str | ||
Character : (c : Char) -> (1 it : StringIterator str) -> UnconsResult str | ||
|
||
-- We pass the whole string to the uncons function | ||
-- to avoid yet another allocation per character | ||
-- because for many backends, StringIterator can be simply an integer | ||
-- (e.g. byte offset into an UTF-8 string). | ||
%foreign | ||
"scheme:blodwen-string-iterator-next" | ||
"javascript:stringIterator:next" | ||
export | ||
uncons : (str : String) -> (1 it : StringIterator str) -> UnconsResult str | ||
|
||
export | ||
foldl : (accTy -> Char -> accTy) -> accTy -> String -> accTy | ||
foldl op acc str = withString str (loop acc) | ||
where | ||
loop : accTy -> (1 it : StringIterator str) -> accTy | ||
loop acc it = | ||
case uncons str it of | ||
EOF => acc | ||
Character c it' => loop (acc `op` c) (assert_smaller it it') | ||
|
||
export | ||
unpack : String -> LazyList Char | ||
unpack str = withString str unpack' | ||
where | ||
unpack' : (1 it : StringIterator str) -> LazyList Char | ||
unpack' it = | ||
case uncons str it of | ||
EOF => [] | ||
Character c it' => c :: Delay (unpack' $ assert_smaller it it') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.