If I get a module called A which imports B and C :
module A exposing (..)
import B
import C
and B also imports C :
module B exposing (..)
import C
What will happen? Does import actually include B and C code, then C would appear twice inside A at compilation? Or does the compiler replace each occurrence of an imported module's member in A or B by its origin code?
Regardless of how many modules another modules is referenced in, it only ever gets compiled once.
Here's an example that takes three files:
A.elm
module A exposing (..)
import B
import C
a : String
a =
"Hi from A!\n" ++ B.b ++ "\n" ++ C.c
B.elm
module B exposing (..)
import C
b : String
b =
"Hi from B!\n" ++ C.c
C.elm
module C exposing (..)
c : String
c =
"Hi from C!"
The resulting transpiled javascript looks like this (your generated js may be different):
var _user$project$C$c = 'Hi from C!';
var _user$project$B$b = A2(_elm_lang$core$Basics_ops['++'], 'Hi from B!\n', _user$project$C$c);
var _user$project$A$a = A2(
_elm_lang$core$Basics_ops['++'],
'Hi from A!\n',
A2(
_elm_lang$core$Basics_ops['++'],
_user$project$B$b,
A2(_elm_lang$core$Basics_ops['++'], '\n', _user$project$C$c)));
As you can see, the C.elm code was only included once.
Related
Suppose we have this simple API:
type FooAPI
= "foo"
:> QueryParam "age" Int
:> Get '[PlainText] Text
Is there a way to link type-level servant's API with a function that will generate URL for it? Like
someMagicFunction :: Proxy api -> SomeTypeFamily api
someMagicFunction = ?
generateURL :: Maybe Int -> Text
generateURL = someMagicFunction (Proxy #FooAPI)
>>> generateURL (Just 42)
"https://somehost/foo?age=42"
>>> generateURL Nothing
"https://somehost/foo"
I want to increase type-safety of URL generation so if I'll add some new parameter to FooAPI it will immediately appear in the type of generateURL and my code will not compile without editing the calls of generateURL.
I'm aware of servant-client library and I know that client function does somewhat similar but I couldn't figure out how to use this library in my case.
I would say that Servant.Links is exactly what you are looking for.
In particular, in your case I would use allLinks to generate a Link corresponding to the URL piece containing the path and query parameters:
>>> linkURI $ allLinks (Proxy #FooAPI) Nothing
foo
>>> linkURI $ allLinks (Proxy #FooAPI) (Just 18)
foo?age=18
Then I would transform the generated Link into an URI where I would specify required scheme and hostname. Here's a fully working module:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
import Data.Proxy
import Data.Text (Text)
import Network.URI
import Servant.API
import Servant.Links
type FooAPI
= "foo"
:> QueryParam "age" Int
:> Get '[PlainText] Text
generateURL :: Maybe Int -> String
generateURL age = show uri
{ uriScheme = "https:"
, uriAuthority = Just nullURIAuth
{ uriRegName = "somehost" }
, uriPath = "/" <> uriPath uri
}
where
uri = linkURI link
link = allLinks (Proxy #FooAPI) age
And demonstration:
>>> generateURL (Just 42)
"https://somehost/foo?age=42"
>>> generateURL Nothing
"https://somehost/foo"
I'm trying to generate the sentence One of my friends on GF using the GF library.
I failed at finding the right method for constructing a prep after a numeral and on creating the relation of one of with the plural noun.
as the class of Noun Phrase shows, Numeral or Digits only have Common Noun or Noun after them.
CountNP
There is a function for this in the Noun module, but unfortunately it's not in the RGL API. The function is CountNP:
CountNP : Det -> NP -> NP ; -- three of them, some of the boys
To use it in your grammar, you need to open the module NounEng. The usual practice is to open non-API modules qualified: instead of open NounEng in { … }, we give it a shorthand, like N: open (N=NounEng) in { … }. Then in the body of the grammar, you need to write N.CountNP. Here's an example, you can copy and paste it into a file called Friend.gf.
resource Friend = open SyntaxEng, LexiconEng, (N=NounEng) in {
oper
one_Det : Det = mkDet (mkNumeral n1_Unit) ;
my_friends_NP : NP = mkNP (mkDet i_Pron pluralNum) friend_N ;
friend : NP = N.CountNP one_Det my_friends_NP ;
}
Predet
Other times when you want to modify an already existing NP, you can use the Predet category. Here are examples (you can paste them into the same file Friend.gf).
-- The RGL includes some Predets, like all, most and only:
all_friends : NP = mkNP all_Predet my_friends_NP ;
most_friends : NP = mkNP most_Predet my_friends_NP ;
only_friends : NP = mkNP only_Predet my_friends_NP ;
If you have two modules, A and B, which should contain two functions, bar and baz, that depend each other's module, this can be implemented by first declaring the functions as empty, and adding methods afterwards:
module Wrapper
module A
const x = 1
function bar end
end # module A
module B
const x = 2
function baz end
end # module B
import .A: bar
import .B: baz
bar(expr) = quote
println("bar", $(B.x))
$expr
end
baz(expr) = quote
println("baz", $(A.x))
$expr
end
end # module Wrapper
However, I have a case where A and B contain macros that depend on bar and baz. Since (I think?) I cannot add methods to a macro from outside a module, they have to be declared inside. But then I cannot circumvent the cyclic imports anymore -- the following fails because WARNING: could not import Wrapper.B into A, leaving B undefined in A:
module Wrapper
module A
import ..Wrapper.B
const x = 1
macro foo(expr)
B.baz(expr)
end
function bar end
end # module A
module B
import ..Wrapper.A
const x = 2
macro foo(expr)
A.bar(expr)
end
function baz end
end # module B
import .A: bar
import .B: baz
bar(expr) = quote
println("bar", $(B.x))
$expr
end
baz(expr) = quote
println("baz", $(A.x))
$expr
end
end # module Wrapper
Is there any possibility how this pattern can be implemented? (Just renaming the foos and moving them into Wrapper is not really an option, since I want the names to be the same...).
I could solve the problem by declaring bar and baz outside of A and B, using and redefining them in the submodules, and finally implementing their methods afterwards:
module Wrapper
function bar end
function baz end
module A
import ..Wrapper
const x = 1
macro foo(expr)
Wrapper.baz(expr)
end
const bar = Wrapper.bar
end # module A
module B
import ..Wrapper
const x = 2
macro foo(expr)
Wrapper.bar(expr)
end
const baz = Wrapper.baz
end # module B
import .A
import .B
bar(expr) = quote
println("bar", $(B.x))
$expr
end
baz(expr) = quote
println("baz", $(A.x))
$expr
end
end # module Wrapper
Result:
julia> Wrapper.A.bar(1)
quote
#= /tmp/test.jl:119 =#
println("bar", 2)
#= /tmp/test.jl:120 =#
1
end
julia> Wrapper.B.baz(1)
quote
#= /tmp/test.jl:124 =#
println("baz", 1)
#= /tmp/test.jl:125 =#
1
end
julia> Wrapper.B.#foo 1
bar2
1
julia> Wrapper.A.#foo 1
baz1
1
I'm trying to learn how to use pipes together with attoparsec by following the tutorial https://hackage.haskell.org/package/pipes-attoparsec-0.1.0.1/docs/Control-Proxy-Attoparsec-Tutorial.html . But I was not able to import Control.Proxy.Trans.Either . In which lib is this module located?
You hit on an old version of pipes-attoparsec corresponding to an old version of pipes. With recent versions, something like the first example would be written without a pipe. We would use the parsed function, which just applies a parser repeatedly until it fails, streaming good parses as they come.
{-# LANGUAGE OverloadedStrings #-}
import Pipes
import qualified Pipes.Prelude as P
import Pipes.Attoparsec
import Data.Attoparsec.Text
import Data.Text (Text)
data Name = Name Text deriving (Show)
hello :: Parser Name
hello = fmap Name $ "Hello " *> takeWhile1 (/='.') <* "."
helloparses :: Monad m => Producer Text m r -> Producer Name m (Either (ParsingError, Producer Text m r) r)
helloparses = parsed hello
process txt = do
e <- runEffect $ helloparses txt >-> P.print
case e of
Left (err,rest) -> print err >> runEffect (rest >-> P.print)
Right () -> return ()
input1, input2 :: Monad m => Producer Text m ()
input1 = each
[ "Hello Kate."
, "Hello Mary.Hello Jef"
, "f."
, "Hel"
, "lo Tom."
]
input2 = input1 >> yield "garbage"
Then we see
-- >>> process input1
-- Name "Kate"
-- Name "Mary"
-- Name "Jeff"
-- Name "Tom"
-- >>> process input2
-- Name "Kate"
-- Name "Mary"
-- Name "Jeff"
-- Name "Tom"
-- ParsingError {peContexts = [], peMessage = "string"}
-- "garbage"
The other principle function pipes-attoparsec defined is just parse. This converts an attoparsec parser into a pipes StateT parser to parse an initial segment of a producer that matches the parser. You can read about them here http://www.haskellforall.com/2014/02/pipes-parse-30-lens-based-parsing.html
This question already has answers here:
elm generate random number
(2 answers)
Closed 7 years ago.
What's a simple way to do this?
The documentation for Random.initialSeed says:
"A good way to get an unexpected seed is to use the current time."
http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Random#initialSeed
After a ton of reading, I can only find "solutions" that are well beyond my understanding of Elm and Functional Programming. They also don't seem to be solutions to this problem.
I'm currently hardcoding:
Random.initialSeed 314
If you use a library, please include the name used to get it from elm package. I've seen a solution that says use Native.now but I can't figure out how to get that one.
stackoverflow is suggesting this one but I can't understand how to apply it to my usecase Elm Current Date
You can try case nelson's answer from How do I get the current time in Elm?
From elm repl:
> import Now
> import Random
> Now.loadTime |> round -- get current time in Int
1455406828183 : Int
> Now.loadTime |> round |> Random.initialSeed -- get the Seed
Seed { state = State 1560073230 678, next = <function>, split = <function>, range = <function> }
: Random.Seed
I also have the code on my repo here.
Note: don't forget "native-modules": true in elm-package.json.
Edit:
to try the code,
git clone https://github.com/prt2121/elm-backup.git
cd elm-backup/now
elm make Now.elm
add "native-modules": true in elm-package.json
elm repl
The simplest way I can think of is to use the Elm Architecture and Effects.tick mechanism to initialise the seed with a time value.
Here is an example of how this works:
import Html exposing (..)
import Html.Events exposing (onClick)
import Random exposing (Seed, generate, int, initialSeed)
import Time exposing (Time)
import Effects exposing (Effects, Never)
import Task exposing (Task)
import StartApp
type alias Model = { seed : Seed, value : Int}
type Action = Init Time | Generate
init : (Model, Effects Action)
init = (Model (initialSeed 42) 0, Effects.tick Init)
modelFromSeed : Seed -> (Model, Effects Action)
modelFromSeed seed =
let
(value', seed') = generate (int 1 1000) seed
in
(Model seed' value', Effects.none)
update : Action -> Model -> (Model, Effects Action)
update action model =
case action of
Init time ->
modelFromSeed (initialSeed (round time))
Generate ->
modelFromSeed model.seed
view : Signal.Address Action -> Model -> Html
view address model =
div []
[ text ("Current value: " ++ (toString model.value))
, br [] []
, button [onClick address Generate] [text "New Value"]
]
app : StartApp.App Model
app = StartApp.start
{ init = init
, update = update
, view = view
, inputs = []
}
main : Signal Html
main = app.html
port tasks : Signal (Task Never ())
port tasks = app.tasks