How do I use the Queue library in SML/NJ - queue

I see that the SML/NJ includes a queue structure. I can't figure out how to use it. How do I use the additional libraries provided by SML/NJ?

The Queue structure is not specified by SML '97, but it is present in SML/NJ's top-level environment.
$ sml
Standard ML of New Jersey v110.69 [built: Fri Mar 13 16:02:47 2009]
- Queue.mkQueue ();
[autoloading]
[library $SMLNJ-LIB/Util/smlnj-lib.cm is stable]
[autoloading done]
stdIn:1.1-1.17 Warning: type vars not generalized because of
value restriction are instantiated to dummy types (X1,X2,...)
val it = - : ?.X1 Queue.queue
-
You can open a structure. This lets you avoid typing Queue. in front of everything. It's discouraged to do this at the top-level, though, because it pollutes the environment and makes it much less obvious what you're depending on. (Within another structure I'd say it might be acceptable in some situations.)
$ sml
Standard ML of New Jersey v110.69 [built: Fri Mar 13 16:02:47 2009]
- open Queue;
[autoloading]
[library $SMLNJ-LIB/Util/smlnj-lib.cm is stable]
[autoloading done]
opening Queue
type 'a queue
exception Dequeue
val mkQueue : unit -> 'a queue
val clear : 'a queue -> unit
val isEmpty : 'a queue -> bool
val enqueue : 'a queue * 'a -> unit
val dequeue : 'a queue -> 'a
val next : 'a queue -> 'a option
val delete : 'a queue * ('a -> bool) -> unit
val head : 'a queue -> 'a
val peek : 'a queue -> 'a option
val length : 'a queue -> int
val contents : 'a queue -> 'a list
val app : ('a -> unit) -> 'a queue -> unit
val map : ('a -> 'b) -> 'a queue -> 'b queue
val foldl : ('a * 'b -> 'b) -> 'b -> 'a queue -> 'b
val foldr : ('a * 'b -> 'b) -> 'b -> 'a queue -> 'b
- mkQueue ();
stdIn:3.1-3.11 Warning: type vars not generalized because of
value restriction are instantiated to dummy types (X1,X2,...)
val it = - : ?.X1 queue
-

I don't have a complete answer for you but I could point you in the right direction. You should look up using the compilation manager (CM) which is built in to SML/NJ. You can think of it as Make for SML.
To use a library from the SML/NJ library you then add smlnj-lib.cm to the CM description file of your application. Then you can use the declarations such as Queue from that library.
The smlnj website has some documentation about the compilation manager.
Hope this at least points you in the right direction.

If you want to create an integer Queue, use the following code. Replace 'int' with the datatype you want.
val que = Queue.mkqueue(): int Queue.queue
Everything else can be found here.

Related

Is there a function that transforms/maps both Either's Left and Right cases taking two transformation functions respectively?

I have not found a function in Scala or Haskell that can transform/map both Either's Left and Right cases taking two transformation functions at the same time, namely a function that is of the type
(A => C, B => D) => Either[C, D]
for Either[A, B] in Scala, or the type
(a -> c, b -> d) -> Either a b -> Either c d
in Haskell. In Scala, it would be equivalent to calling fold like this:
def mapLeftOrRight[A, B, C, D](e: Either[A, B], fa: A => C, fb: B => D): Either[C, D] =
e.fold(a => Left(fa(a)), b => Right(fb(b)))
Or in Haskell, it would be equivalent to calling either like this:
mapLeftOrRight :: (a -> c) -> (b -> d) -> Either a b -> Either c d
mapLeftOrRight fa fb = either (Left . fa) (Right . fb)
Does a function like this exist in the library? If not, I think something like this is quite practical, why do the language designers choose not to put it there?
Don't know about Scala, but Haskell has a search engine for type signatures. It doesn't give results for the one you wrote, but that's just because you take a tuple argument while Haskell functions are by convention curried†. https://hoogle.haskell.org/?hoogle=(a -> c) -> (b -> d) -> Either a b -> Either c d does give matches, the most obvious being:
mapBoth :: (a -> c) -> (b -> d) -> Either a b -> Either c d
...actually, even Google finds that, because the type variables happen to be exactly as you thought. (Hoogle also finds it if you write it (x -> y) -> (p -> q) -> Either x p -> Either y q.)
But actually, as Martijn said, this behaviour for Either is only a special case of a bifunctor, and indeed Hoogle also gives you the more general form, which is defined in the base library:
bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d
†TBH I'm a bit disappointed that Hoogle doesn't by itself figure out to curry the signature or to swap arguments. Pretty sure it actually used to do that automatically, but at some point they simplified the algorithm because with the huge number of libraries the time it took and number of results got out of hand.
Cats provides Bifunctor, for example
import cats.implicits._
val e: Either[String, Int] = Right(41)
e.bimap(e => s"boom: $e", v => 1 + v)
// res0: Either[String,Int] = Right(42)
The behaviour you are talking about is a bifunctor behaviour, and would commonly be called bimap. In Haskell, a bifunctor for either is available: https://hackage.haskell.org/package/bifunctors-5/docs/Data-Bifunctor.html
Apart from the fold you show, another implementation in scala would be either.map(fb).left.map(fa)
There isn't such a method in the scala stdlib, probably because it wasn't found useful or fundamental enough. I can somewhat relate to that: mapping both sides in one operation instead of mapping each side individually doesn't come across as fundamental or useful enough to warrant inclusion in the scala stdlib to me either. The bifunctor is available in Cats though.
In Haskell, the method exists on Either as mapBoth and BiFunctor is in base.
In Haskell, you can use Control.Arrow.(+++), which works on any ArrowChoice:
(+++) :: (ArrowChoice arr) => arr a b -> arr c d -> arr (Either a c) (Either b d)
infixr 2 +++
Specialised to the function arrow arr ~ (->), that is:
(+++) :: (a -> b) -> (c -> d) -> Either a c -> Either b d
Hoogle won’t find +++ if you search for the type specialised to functions, but you can find generalised operators like this by replacing -> in the signature you want with a type variable: x a c -> x b d -> x (Either a b) (Either c d).
An example of usage:
renderResults
:: FilePath
-> Int
-> Int
-> [Either String Int]
-> [Either String String]
renderResults file line column
= fmap ((prefix ++) +++ show)
where
prefix = concat [file, ":", show line, ":", show column, ": error: "]
renderResults "test" 12 34 [Right 1, Left "beans", Right 2, Left "bears"]
==
[ Right "1"
, Left "test:12:34: error: beans"
, Right "2"
, Left "test:12:34: error: bears"
]
There is also the related operator Control.Arrow.(|||) which does not tag the result with Either:
(|||) :: arr a c -> a b c -> arr (Either a b) c
infixr 2 |||
Specialised to (->):
(|||) :: (a -> c) -> (b -> c) -> Either a b -> c
Example:
assertRights :: [Either String a] -> [a]
assertRights = fmap (error ||| id)
sum $ assertRights [Right 1, Right 2]
==
3
sum $ assertRights [Right 1, Left "oh no"]
==
error "oh no"
(|||) is a generalisation of the either function in the Haskell Prelude for matching on Eithers. It’s used in the desugaring of if and case in arrow proc notation.

How to convert partial functions to safe(Maybe) functions?

I want it to use library-defined partialfunc more convenient, or write callback with partial pattern-matching.
like this,
partialMaybe :: forall a b. (Partial => a -> b) -> a -> Maybe b
I couldn't find similar in some major libraries.
How to define it? or already defined in libs?
data ABC a = A a | B a | C a
f1 = someHigherOrderFunc $ partialMaybe \(A a) -> someFunc a -- if not 'A', return Nothing.
-- same as
f2 = someHigherOrderFunc $ case _ of A a -> Just $ someFunc a
_ -> Nothing -- requires line break, seems syntax redundant...
using: purescript 0.11.6
Edit:
I did it...
partialMaybe :: forall a b. (Partial => a -> b) -> a -> Maybe b
partialMaybe f a = runPure $ catchException (const $ pure Nothing) (Just <<< unsafePartial f <$> pure a)
this is...umm...very ugly. it's not.
'Failed pattern match' exception is thrown by the purescript.
so I think it should be able to handle by purescript.
Can't do it?
If you want an exception if a case is missed, use Partial. If you want otherwise, use Maybe or Either or another appropriate sum type.
You can catch the exception thrown from a failed pattern match. There is no way for a failed pattern match to not throw an exception.

A simple example of rest api in servant or "how to mix monads properly"?

I want to build a simple example of a rest api in servant 0.5:
data MyData = MyData { var1 :: Int, var2 :: String }
app :: Application
app = serve api server
api :: Proxy API
api = Proxy
server :: Server API
server = getItems
getItems :: EitherT ServantErr IO [MyData]
getItems = runEitherT $ do
aa <- nextRandom -- IO
bb <- getCurrentTime -- IO
cc <- getDataFromDb -- IO
--noteT ??? How???
--MaybeT ??? How???
return $ Just [MyData 111 222]
startApp :: IO ()
startApp = run 8080 app
I can't make it compile because of lots errors of "Couldn't match expected type" in different places. I guess it's because I'm mixing 2 different monads in "getItems". But not only.
Here:
getItems :: ExceptT ServantErr IO [MyData]
getItems = runExceptT $ do
What runExceptT does is going from ExceptT ServantErr IO [MyData] to IO (Either ServantErr [MyData]. It eliminates the ExceptT newtype. But you want to go the other way!
You can use liftIO to lift any IO a action into a ExceptT ServantErr IO a action. It basically tells the ExceptT wrapper to "just put the result of the IO action in a success context".
Since your whole do-block seems to live in IO, you could just write:
getItems :: ExceptT ServantErr IO [MyData]
getItems = liftIO $ do
aa <- nextRandom -- IO
bb <- getCurrentTime -- IO
cc <- getDataFromDb -- IO
...
Instead of lifting each IO action separately.
Other common cases:
If you have a pure Either, use hoistEither :: Monad m => Either e a -> ExceptT e m a to lift it into ExceptT.
If you have a pure Maybe, use failWith :: Applicative m => e -> Maybe a -> ExceptT e m a and provide the error.
If you have a IO (Maybe a), use failWithM :: Applicative m => e -> m (Maybe a) -> ExceptT e m a and provide the error.
If you have a IO (Either e a), just wrap it in the ExceptT constructor.
To change the error type carried by an ExceptT, use withExcept :: (e -> e') -> Except e a -> Except e' a.
All these functions are quite simple and looking at their source code is instructive.

how can i make a queue in ml

i am writting a program in ml and i am trying to make a queue that consists of a tuple of integers.But it doesnt work!here is my code.
let
val fif1 = Queue.mkQueue (() ,() )
in #2 (bfs1 (array1, 0, n, Queue.enqueue (fif1 , (c,0) ) ))
end
where c is an integer.
the compiler error is this:
Error: operator and operand don't agree [type mismatch]
operator domain: {2:'Y; 'Z}
operand: square array * 'X * int * (int * int) Queue.queue
-> square array * int * int * (int * int) Queue.queue
in expression:
(fn {2=2,...} => 2) bfs1
any help would be very very useful!thanks in advance!
I assume you are using the Queue structure in SML/NJ.
Very briefly, that's an implementation of mutable queues. The signature provides the constructor mkQueue which has the type unit -> 'a queue. You're calling mkQueue with a value of type unit * unit:
Queue.mkQueue ((), ())
No matter what type of queue you want, you should call mkQueue with just (). Here's an example, this makes a new queue and adds a couple of pairs of ints to it:
Construct the queue (I had to add a type annotation at the REPL due to the value restriction, you may not have to do this in a source file that you compile, I'm not sure)
val q = Queue.mkQueue () : (int * int) Queue.queue
Then add two things to it:
val _ = ( Queue.enqueue (q, (1, 2))
; Queue.enqueue (q, (3, 4)))
Get them out, pattern match with constants to confirm that it's working:
val (1, 2) = Queue.dequeue q
val (3, 4) = Queue.dequeue q
Your error message is a bit perplexing to me, it looks like you're trying to apply #2 (which selects the second element from a tuple) from the function bfs1, which of course is not a tuple. But your code is properly parenthesized, so I wonder if you loaded some older code that caused that message?
Try to load the folloing code in a fresh REPL, along with the rest of your code (i.e. stop the SML/NJ process altogether and start a new one with your code). It's hard for me otest this has there's some code missing (the variables c, n, array1, bfs1)
let
val fif1 = Queue.mkQueue ()
in
#2 (bfs1 (array1, 0, n, Queue.enqueue (fif1, (c, 0))))
end

Folding flatMap/bind over a list of functions (a.k.a. Name That Combinator!)

In the process of writing a simple RPN calculator, I have the following type aliases:
type Stack = List[Double]
type Operation = Stack => Option[Stack]
... and I have written a curious-looking line of Scala code:
val newStack = operations.foldLeft(Option(stack)) { _ flatMap _ }
This takes an initial stack of values and applies a list of operations to that stack. Each operation may fail (i.e. yields an Option[Stack]) so I sequence them with flatMap. The thing that's somewhat unusual about this (in my mind) is that I'm folding over a list of monadic functions, rather than folding over a list of data.
I want to know if there's a standard function that captures this "fold-bind" behavior. When I'm trying to play the "Name That Combinator" game, Hoogle is usually my friend, so I tried the same mental exercise in Haskell:
foldl (>>=) (Just stack) operations
The types here are:
foldl :: (a -> b -> a) -> a -> [b] -> a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
So the type of my mystery foldl (>>=) combinator, after making the types of foldl and (>>=) line up, should be:
mysteryCombinator :: Monad m => m a -> [a -> m a] -> m a
... which is again what we'd expect. My problem is that searching Hoogle for a function with that type yields no results. I tried a couple other permutations that I thought might be reasonable: a -> [a -> m a] -> m a (i.e. starting with a non-monadic value), [a -> m a] -> m a -> m a (i.e. with arguments flipped), but no luck there either. So my question is, does anybody know a standard name for my mystery "fold-bind" combinator?
a -> m a is just a Kleisli arrow with the argument and result types both being a. Control.Monad.(>=>) composes two Kleisli arrows:
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
Think flip (.), but for Kleisli arrows instead of functions.
So we can split this combinator into two parts, the composition and the "application":
composeParts :: (Monad m) => [a -> m a] -> a -> m a
composeParts = foldr (>=>) return
mysteryCombinator :: (Monad m) => m a -> [a -> m a] -> m a
mysteryCombinator m fs = m >>= composeParts fs
Now, (>=>) and flip (.) are related in a deeper sense than just being analogous; both the function arrow, (->), and the data type wrapping a Kleisli arrow, Kleisli, are instances of Control.Category.Category. So if we were to import that module, we could in fact rewrite composeParts as:
composeParts :: (Category cat) => [cat a a] -> cat a a
composeParts = foldr (>>>) id
(>>>) (defined in Control.Category) is just a nicer way of writing as flip (.).
So, there's no standard name that I know of, but it's just a generalisation of composing a list of functions. There's an Endo a type in the standard library that wraps a -> a and has a Monoid instance where mempty is id and mappend is (.); we can generalise this to any Category:
newtype Endo cat a = Endo { appEndo :: cat a a }
instance (Category cat) => Monoid (Endo cat a) where
mempty = Endo id
mappend (Endo f) (Endo g) = Endo (f . g)
We can then implement composeParts as:
composeParts = appEndo . mconcat . map Endo . reverse
which is just mconcat . reverse with some wrapping. However, we can avoid the reverse, which is there because the instance uses (.) rather than (>>>), by using the Dual a Monoid, which just transforms a monoid into one with a flipped mappend:
composeParts :: (Category cat) => [cat a a] -> cat a a
composeParts = appEndo . getDual . mconcat . map (Dual . Endo)
This demonstrates that composeParts is a "well-defined pattern" in some sense :)
The one starting with a non-monadic value is (modulo flip)
Prelude> :t foldr (Control.Monad.>=>) return
foldr (Control.Monad.>=>) return
:: Monad m => [c -> m c] -> c -> m c
(or foldl)
(Yes, I know this doesn't answer the question, but the code layout in comments isn't satisfactory.)