Purescript Tutorial: unknown value logShow - purescript

I am about an hour into learning PureScript and I've hit a snag going through the PureScript by Example Tutorial which PureScript recommended on their site. (Specifically I'm in section 2.10). I have managed to get everything installed and I am attempting to use the logShow method they describe in the tutorial. I am getting an Unknown value logShow error when I run this code:
module Main where
import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Math (sqrt)
main :: forall e. Eff (console :: CONSOLE | e) Unit
main = logShow (diagonal 3.0 4.0)
diagonal w h = sqrt(w * w + h * h)
I assume that logShow is a method intended to log an integer since the actual log method only takes strings. Where is this method defined? Am I failing to import something? Is my installation incorrect? Or is the tutorial skipping something?
Thanks in advance!

You're almost there.
Notice this line:
import Control.Monad.Eff.Console (CONSOLE, log)
Control.Monad.Eff.Console offers both log and logShow. To solve your particular problem, you just need to replace log between those parens with logShow (the first name after the (, CONSOLE, is the name of Effect).
Just in case -- The difference between the two can be seen by the types:
log :: forall eff. String -> Eff (console :: CONSOLE | eff) Unit
logShow :: forall a eff. Show a => a -> Eff (console :: CONSOLE | eff) Unit
Ignoring the effects for a moment...
log :: String -> Unit
logShow :: forall a. Show a => a -> Unit
log only prints strings, while logShow prints anything that has a Show instance.
Realistically, yes; it means logShow is simply (log <<< show). And if we go look at the source... We can find it's indeed the case.

Related

What is the advantage of Option/Maybe Monad over Functor?

I understand the advantage of IO monad and List Monad over Functor, however, I don't understand the advantage of Option/Maybe Monad over Functor.
Is that simply the integration of types of the language?
or
What is the advantage of Option/Maybe Monad over Functor in specific use?
PS. asking the advantage in specific use is not opinion-based because if there is, it can be pointed out without subjective aspect.
PS.PS. some member here is so eager to push repeatedly
Option is both a functor and a monad?
should be the answer, or QA is duplicate, but actually not.
I already know the basics such as
Every monad is an applicative functor and every applicative functor is a functor
as the accepted answer there, and that is not what I'm not asking here.
Having an excellent answer here that is Not included in the previous QA.
The aspect, detail, or resolution of each question is quite different, so please avoid "bundling" different things in rough manner here.
Let's look at the types.
fmap :: Functor f => (a -> b) -> (f a -> f b)
(<*>) :: Applicative f => f (a -> b) -> (f a -> f b)
flip (>>=) :: Monad f => (a -> f b) -> (f a -> f b)
For a functor, we can apply an ordinary function a -> b to a value of type f a to get a value of type f b. The function never gets a say in what happens to the f part, only the inside. Thinking of functors as sort of box-like things, the function in fmap never sees the box itself, just the inside, and the value gets taken out and put back into the exact same box it started at.
An applicative functor is slightly more powerful. Now, we have a function which is also in a box. So the function gets a say in the f part, in a limited sense. The function and the input each have f parts (which are independent of each other) which get combined into the result.
A monad is even more powerful. Now, the function does not, a priori, have an f part. The function takes a value and produces a new box. Whereas in the Applicative case, our function's box and our value's box were independent, in the Monad case, the function's box can depend on the input value.
Now, what's all this mean? You've asked me to focus on Maybe, so let's talk about Maybe in the concrete.
fmap :: (a -> b) -> (Maybe a -> Maybe b)
(<*>) :: Maybe (a -> b) -> (Maybe a -> Maybe b)
flip (>>=) :: (a -> Maybe b) -> (Maybe a -> Maybe b)
As a reminder, Maybe looks like this.
data Maybe a = Nothing | Just a
A Maybe a is a value which may or may not exist. From a functor perspective, we'll generally think of Nothing as some form of failure and Just a as a successful result of type a.
Starting with fmap, the Functor instance for Maybe allows us to apply a function to the inside of the Maybe, if one exists. The function gets no say over the success or failure of the operation: A failed Maybe (i.e. a Nothing) must remain failed, and a successful one must remain successful (obviously, we're glossing over undefined and other denotational semantic issues here; I'm assuming that the only way a function can fail is with Nothing).
Now (<*>), the applicative operator, takes a Maybe (a -> b) and a Maybe a. Either of those two might have failed. If either of them did, then the result is Nothing, and only if the two both succeeded do we get a Just as our result. This allows us to curry operations. Concretely, if I have a function of the form g :: a -> b -> c and I have values ma :: Maybe a and mb :: Maybe b, then we might want to apply g to ma and mb. But when we start to do that, we have a problem.
fmap g ma :: Maybe (b -> c)
Now we've got a function that may or may not exist. We can't fmap that over mb, because a nonexistent function (a Nothing) can't be an argument to fmap. The problem is that we have two independent Maybe values (ma and mb in our example) which are fighting, in some sense, for control. The result should only exist if both are Just. Otherwise, the result should be Nothing. It's sort of a Boolean "and" operation, in that if any of the intermediates fail, then the whole calculation fails. (Note: If you're looking for a Boolean "or", where any individual success can recover from prior failure, then you're looking for Alternative)
So we write
(fmap g ma) <*> mb :: Maybe c
or, using the more convenient synonym Haskell provides for this purpose,
g <$> ma <*> mb :: Maybe c
Now, the key word in the above situation is independent. ma and mb have no say over the other's success or failure. This is good in many cases, because code like this can often be parallelized (there are very efficient command line argument parsing libraries that exploit just this property of Applicative). But, obviously, it's not always what we want.
Enter Monad. In the Maybe monad, the provided function produces a value of type Maybe b based on the input a. The Maybe part of the a and of the b are no longer independent: the latter can depend directly on the former.
For example, take the classic example of Maybe: a square root function. We can't take a square root of a negative number (let's assume we're not working with complex numbers here), so our hypothetical square root looks like
sqrt :: Double -> Maybe Double
sqrt x | x < 0 = Nothing
| otherwise = Just (Prelude.sqrt x)
Now, suppose we've got some number r. But r isn't just a number. It came from earlier in our computation, and our computation might have failed. Maybe it did a square root earlier, or tried to divide by zero, or something else entirely, but it did something that has some chance of producing a Nothing. So r is Maybe Double, and we want to take its square root.
Obviously, if r is already Nothing, then its square root is Nothing; we can't possibly take a square root if we've already failed to compute everything else. On the other hand, if r is a negative number, then sqrt is going to fail and produce Nothing despite the fact that r is itself Just. So what we really want is
case r of
Nothing -> Nothing
Just r' -> sqrt r'
And this is exactly what the Monad instance for Maybe does. That code is equivalent to
r >>= sqrt
The result of this entire computation (and, namely, whether or not it is Nothing or Just) depends not just on whether or not r is Nothing but also on r's actual value. Two different Just values of r can produce success or failure depending on what sqrt does. We can't do that with just a Functor, we can't even do that with Applicative. It takes a Monad.

PureScript - Replace `launchAff_` with `launchAff`

Consider the following working code example, that uses launchAff_ to copy a JSON file:
module Main where
import Prelude
import Effect (Effect)
import Effect.Aff (Aff, launchAff_)
import Node.Encoding (Encoding(..))
import Node.FS.Aff (readTextFile, writeTextFile)
import Node.Path (FilePath)
duplicateCustomerData :: FilePath -> FilePath -> Aff Unit
duplicateCustomerData filePath1 filePath2 = do
customer_data <- readTextFile UTF8 filePath1
writeTextFile UTF8 filePath2 customer_data
main :: Effect Unit
main = launchAff_ do
duplicateCustomerData "database/customer-1.json" "database/customer-2.json"
However, if the main function is changed to use launchAff (without the underscore) like so
main :: Effect Unit
main = launchAff do
duplicateCustomerData "database/customer-1.json" "database/customer-2.json"
The following error is thrown:
Could not match type
Fiber Unit
with type
Unit
Thus,
What is a fiber unit?
What is the use case for this fiber unit? Is it meant to be discarded? What does it represent?
Why are there two launchAff functions?
Fiber represents a running async computation.
The difference between Fiber and Aff is the "running" part. Aff is not an async computation that is running, but rather a way to start an async computation. It's not started until you bind it in a larger computation. And conversely, you can start the same Aff multiple times.
Fiber, on the other hand, is an async computation that has already been started, it's already in progress. You can kill it via killFiber or you can wait for it to complete via joinFiber, and some other things. See the docs.
And now that we know that (1) Aff is a way to start an async computation, and (2) Fiber is an already-running async computation, it should become obvious that a Fiber would be the result of starting an Aff. Which is exactly what you observe: launchAff takes an Aff and returns a Fiber.
But sometimes (in my own experience - most times) we don't actually need the resulting Fiber. There is nothing we're going to do with it. For those cases, there is a convenience shortcut - launchAff_. It does the same thing as launchAff, but throws away the resulting Fiber. See it for yourself in the source code.
Adding an underscore at the end to mean "returns unit" is a common pattern. For example, there are for and for_, there are traverse and traverse_, there are runAff and runAff_.

How to set implicit parameters for constructor

Playing with nostutter excersizes I found another odd behaviour. Here is the code:
Inductive nostutter {X:Type} : list X -> Prop :=
| ns_nil : nostutter []
| ns_one : forall (x : X), nostutter [x]
| ns_cons: forall (x : X) (h : X) (t : list X), nostutter (h::t) -> x <> h -> nostutter (x::h::t).
Example test_nostutter_manual: not (nostutter [3;1;1;4]).
Proof.
intro.
inversion_clear H.
inversion_clear H0.
unfold not in H2.
(* We are here *)
specialize (H2 eq_refl).
apply H2.
Qed.
Status after unfold is this:
1 subgoal (ID 229)
H1 : 3 <> 1
H : nostutter [1; 4]
H2 : 1 = 1 -> False
============================
False
When I run specialize (H2 eq_refl). inside IndProp.v that loads other Logical foundations files, it works. Somehow it understands that it needs to put "1" as a parameter. Header of IndProp.v is this:
Set Warnings "-notation-overridden,-parsing".
From LF Require Export Logic.
Require Import String.
Require Coq.omega.Omega.
When I move the code into another file "nostutter.v", this same code gives an expected error:
The term "eq_refl" has type "RelationClasses.Reflexive Logic.eq" while
it is expected to have type "1 = 1".
Header of nostutter.v:
Set Warnings "-notation-overridden,-parsing".
Require Import List.
Import ListNotations.
Require Import PeanoNat.
Import Nat.
Local Open Scope nat_scope.
I have to explicitly add a parameter to eq_refl: specialize (H2 (eq_refl 1)).
I think it's not related specifically to specialize. What is it? How to fix?
The problem is importing PeanoNat.Nat.
When you import PeanoNat, the module type Nat comes into scope, so importing Nat brings in PeanoNat.Nat. If you meant to import Coq.Init.Nat, you'll either have to import it before importing PeanoNat, or import it with Import Init.Nat..
Why does importing PeanoNat.Nat cause trouble in this case?
Arith/PeanoNat.v (static link) contains the module1 Nat. Inside that module, we find2 the unusual looking line
Include NBasicProp <+ UsualMinMaxLogicalProperties <+ UsualMinMaxDecProperties.
All this means is that each of NBasicProp, UsualMinMaxLogicalProperties and UsualMinMaxDecProperties are included, which in turn means that everything defined in those modules is included in the current module. Separating this line out into three Include commands, we can figure out which one is redefining eq_refl. It turns out to be NBasicProp, which is found in this file (static link). We're not quite there yet: the redefinition of eq_refl isn't here. However, we see the definition of NBasicProp in terms of NMaxMinProp.
This leads us to NMaxMin.v, which in turn leads us to NSub.v, which leads us to NMulOrder.v, which leads us to NAddOrder.v, which leads us to NOrder.v, which leads us to NAdd.v, which leads us to NBase.v, ...
I'll cut to the chase here. Eventually we end up in Structures/Equality.v (static link) with the module BackportEq which finally gives us our redefinition of eq_refl.
Module BackportEq (E:Eq)(F:IsEq E) <: IsEqOrig E.
Definition eq_refl := #Equivalence_Reflexive _ _ F.eq_equiv.
Definition eq_sym := #Equivalence_Symmetric _ _ F.eq_equiv.
Definition eq_trans := #Equivalence_Transitive _ _ F.eq_equiv.
End BackportEq.
The way this is defined, eq_refl (without any arguments) has type Reflexive eq, where Reflexive is the class
Class Reflexive (R : relation A) :=
reflexivity : forall x : A, R x x.
(found in Classes/RelationClasses.v)
So that means that we'll always need to supply an extra argument to get something of type x = x. There are no implicit arguments defined here.
Why is importing modules like PeanoNat.Nat generally a bad idea?
If the wild goose chase above wasn't convincing enough, let me just say that modules like this one, which extend and import other modules and module types, are often not meant to be imported. They often have short names (like N, Z or Nat) so any theorem you want to use from them is easily accessible without having to type out a long name. They usually have a long chain of imports and thus contain a vast number of items. If you import them, now that vast number of items is polluting your global namespace. As you saw with eq_refl, that can cause unexpected behavior with what you thought was a familiar constant.
Most of the modules encountered in this adventure are of the "module type/functor" variety. Suffice to say, they're difficult to understand fully, but a short guide can be found here.
My sleuthing was done by opening files in CoqIDE and running the command Locate eq_refl. (or better yet, ctrl+shift+L) after anything that might import from elsewhere. Locate can also tell you where a constant was imported from. I wish there were an easier way to see the path of imports in module types, but I don't think so. You could guess that we'd end up in Coq.Classes.RelationClasses based on the type of the overwritten eq_refl, but that isn't as precise.

How to evaluate an Eff monad in psci?

I'm learning Purescript using the purescript-node-http library. If I have a value whose type is the following:
> :t f
forall t3.
Eff
( http :: HTTP
, console :: CONSOLE
| t3
)
Request
How would I be able to evaluate this in psci and assign the Request return value to a variable?
You can't bind the result to a variable right now. That feature might be supported in a later version. Note that you can evaluate the result and print it out.
If you use the browser as your evaluation environment (with --port) then one option is to store the result in a Ref and use the Ref later to retrieve the value.
The problem with the Node backend is that there is no persistent state, so that approach would not be possible at all with the Node backend.

Help with Haskell dynamic plugin load

I'm a Haskell beginner, and I'm trying to use the dynamic loading in the 'plugins' package. I'm kind of lost. Here is a minimal program with two files.
Main.hs:
module Main (main) where
import System.Plugins
main :: IO ()
main = do
putStrLn "Loading"
mv <- dynload "Plug.o" [] [] "thing" -- also try 'load' here
putStrLn "Loaded"
case mv of
LoadFailure msgs -> putStrLn "fail" >> print msgs
LoadSuccess _ v -> putStrLn "success" >> print (v::Integer)
And Plug.hs:
module Plug (thing) where
thing :: Integer
thing = 1234000
I compile Plug with ghc -c Plug.hs which produces Plug.o. I then compile Main.hs with ghc -o Main Main.hs, and run Main. I also try replacing load with dynload, and running with runhaskell. Only one of these four combinations works. What am I doing wrong?
with dynload
compiled → prints "Loaded", then seg faults
runhaskell → prints "Loading", then "Main.hs: Prelude.undefined"
with load
compiled → successful, prints the Integer
runhaskell → prints "Loading", hangs for 5-10 seconds, disappears
I'm on Mac OS X. GHC version 7.0.2. What am I doing wrong?
thanks,
Rob
Update
I can fix the compiled dynload by changing Plug.hs to the following...
module Plug (thing) where
import Data.Dynamic
thing :: Dynamic
thing = toDyn (1234000::Integer)
It would be nice if it didn't seg fault on error. I guess it doesn't have enough meta data in Plug.o to check the type. Anyway, that leaves the runhaskell cases. I filed a bug for those.
I've tried your example under Ubuntu 10.10 with GHC 6.12.1 and the results are: both dynload and load with running both complied or through runhaskell gives me "Prelude.undefined" error, so I think you should report a bug to the developers.
I cannot see any special cases nor conditions in their module's haddock documentation, so I don't think you doing anything wrong.
You might want to take a look at a similar problem with the GHC-API on haskell ghc dynamic compliation only works on first compile.