Menu variable not in scope Haskell - variables

I am trying to create a menu which read the data from a textfile. But I get three errors that variable not in scope despite having at the start of the IO(). Am I not reading the txt.file properly and is the way I creating the menu wrong?
errors
Variable not in scope: spaDatabase :: [Spa]
--line of error for spaDatabase
let updatedDB = (addSpa rid br ar (read st) spaDatabase)
Variable not in scope: spaDB
Variable not in scope: updatedDB :: [Spa]
--line of error for updatedDB
2 -> putStrLn (spaListStr updatedDB) >> menu spaDB
My code
main :: IO()
main = do
contents <- readFile "spa.txt"
let spaDatabase = (read contents :: [Spa])
menu spaDatabase
putStrLn ""
where menu spaDatabase = do
putStrLn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
putStrLn "\nPlease select an option:"
putStrLn "1: Add a new spa to the database "
putStrLn "2: Show all spa "
putStr "\nSelected option: "
putStrLn ""
option <- getLine
putStrLn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
output :: Int -> IO ()
output option = do
case option of 1 -> do putStrLn "Enter Spa ID: "
rid <- getLine
putStrLn "Enter Spa Brand Name: "
br <- getLine
putStrLn "Enter Spa Area: "
ar <- getLine
putStrLn "Enter Spa Stars: "
st <- getLine
let updatedDB = (addSpa rid br ar (read st) spaDatabase)
putStrLn (spaListStr updatedDB)
writeFile "spa.txt" (spaListStr updatedDB)
2 -> putStrLn (spaListStr updatedDB) >> menu spaDB

where is part of a definition, not of expression. It belongs to the main's definition so its scope goes above do's. Your originally posted code
main = do { .....
let c = .....
.....
}
where
a = ....
b = ....c....
.....
is equivalent to
main = let { -- where's translation
a = ....
b = ....c....
.....
}
in
do {
.....
let c = .....
.....
}
You're using c in b = ....c.... before it is introduced with let c = ....., i.e. outside of its scope region. That's an error, "variable not in scope".
update. let in do blocks is just a shortcut:
do {
.....
let c = .....
.....
}
is the same as
do {
.....
let c = .....
in do {
.....
}
}
The working code could be structured, as also #chi proposed in the comments, as
main = do { .....
let c = .....
.....
let { a = ....
b = ....c....
}
.....
}
That way a and b are in c's scope, so may use c as part of their definitions.

Related

How to load a module inside a custom module in Ejabberd?

I'm creating a custom module which uses some exported functions from mod_shared_roster module. Here is the code.
-module(mod_shared_roster_extra).
-author('https://github.com/eric-mendoza').
-behaviour(gen_mod).
-include("logger.hrl").
-include("translate.hrl").
-export([start/2, stop/1, reload/3, mod_options/1,
get_commands_spec/0, depends/2, mod_doc/0]).
% Commands API
-export([
% Shared roster
srg_display_group_add/4, srg_display_group_del/4, srg_set_opts/4
]).
-include("ejabberd_commands.hrl").
-include("mod_roster.hrl").
-include("mod_privacy.hrl").
-include("ejabberd_sm.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_shared_roster.hrl").
%%%
%%% gen_mod
%%%
start(_Host, _Opts) ->
ejabberd_commands:register_commands(get_commands_spec()).
stop(Host) ->
case gen_mod:is_loaded_elsewhere(Host, ?MODULE) of
false ->
ejabberd_commands:unregister_commands(get_commands_spec());
true ->
ok
end.
reload(_Host, _NewOpts, _OldOpts) ->
ok.
depends(_Host, _Opts) ->
[{mod_shared_roster, hard}].
%%%
%%% Register commands
%%%
get_commands_spec() ->
[
#ejabberd_commands{name = srg_display_group_add, tags = [shared_roster_group],
desc = "Add group id to the Shared Roster Group display list",
module = ?MODULE, function = srg_display_group_add,
args = [{displaygroup, binary}, {displaygrouphost, binary}, {group, binary}, {grouphost, binary}],
args_example = [<<"group1">>, <<"myserver.com">>, <<"group3">>, <<"myserver.com">>],
args_desc = ["Group to be added in display list", "Group server name", "Group to modify display list identifier", "Group server name"],
result = {res, rescode}},
#ejabberd_commands{name = srg_display_group_del, tags = [shared_roster_group],
desc = "Delete group id from the Shared Roster Group",
module = ?MODULE, function = srg_display_group_del,
args = [{displaygroup, binary}, {displaygrouphost, binary}, {group, binary}, {grouphost, binary}],
args_example = [<<"group1">>, <<"myserver.com">>, <<"group3">>, <<"myserver.com">>],
args_desc = ["Group to be removed from display list", "Group server name", "Group to modify display list identifier", "Group server name"],
result = {res, rescode}},
#ejabberd_commands{name = srg_set_opts, tags = [shared_roster_group],
desc = "Update Shared Roster Group options (name and description)",
module = ?MODULE, function = srg_set_opts,
args = [{name, binary}, {description, binary}, {group, binary}, {grouphost, binary}],
args_example = [<<"Group Test Name">>, <<"Group used for testing.">>, <<"group3">>, <<"myserver.com">>],
args_desc = ["Shared roster group name", "Shared Roster Group description", "Group identifier", "Group server name"],
result = {res, rescode}}
].
%%%
%%% Shared Roster Groups
%%%
to_list([]) -> [];
to_list([H|T]) -> [to_list(H)|to_list(T)];
to_list(E) when is_atom(E) -> atom_to_list(E);
to_list(E) -> binary_to_list(E).
srg_display_group_add(NewGroup, NewGroupHost, Group, GroupHost) ->
?DEBUG("Adding group to display list.", []),
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
mod_shared_roster:set_group_opts(GroupHost, Group, Opts),
ok.
srg_display_group_del(DeleteGroup, DeleteGroupHost, Group, GroupHost) ->
?DEBUG("Removing group from display list.", []),
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
%% mod_shared_roster:set_group_opts(GroupHost, Group, Opts),
ok.
srg_set_opts(Label1, Description1, Group, GroupHost) ->
?DEBUG("Setting group options -> Label: ~p, Description: ~p~n", [Label1, Description1]),
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
Label = if Label1 == <<"">> -> [];
true -> [{label, Label1}]
end,
Description = if Description1 == <<"">> -> [];
true -> [{description, Description1}]
end,
Displayed1 = get_opt(Opts, displayed_groups, []),
Displayed = if Displayed1 == [] -> [];
true -> [{displayed_groups, Displayed1}]
end,
?DEBUG("Options: ~p~n", [Label ++ Description ++ Displayed]),
mod_shared_roster:set_group_opts(GroupHost, Group, Label ++ Description ++ Displayed),
ok.
mod_options(_) -> [].
get_opt(Opts, Opt, Default) ->
case lists:keysearch(Opt, 1, Opts) of
{value, {_, Val}} -> Val;
false -> Default
end.
mod_doc() ->
#{desc =>
?T("This module provides additional administrative commands for shared rosters.")}.
Module installs correctly, but when I call the method srg_set_opts which uses mod_shared_roster:get_group_opts I get the following error:
error: {module_not_loaded, mod_shared_roster, <<"srg_group10">>}
I've seen other modules as guide, and the only difference I've noticed is those modules dependencies are contained in the same directory. But, how could I achieve that with a custom module? I'm not experienced with Erlang, so it could be just a simple import.
I'm using ejabberd 20.04 installed via docker-ejabberd, and used Ejabberd module docs for Docker to install the module.
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
I think the arguments of that function are the Host and then the Group, but you provide them in the reverse order.

How to invoke swift function from lldb using address (pointer)?

I'm playing with lldb and I'm trying to call my swift static function. I was able to find its details in image, however I have no idea how to call it and pass arguments.
My output:
(lldb) image lookup -vs $S5project19ViewControllerUtilsC07setRootbC010storyboard13withAnimationySo12UIStoryboardC_SbtFZ
1 symbols match '$S5project19ViewControllerUtilsC07setRootbC010storyboard13withAnimationySo12UIStoryboardC_SbtFZ' in /Users/user/Library/Developer/CoreSimulator/Devices/DC7A5199-424E-4E38-A8A8-CB99C7D8CF82/data/Containers/Bundle/Application/BE7BB249-DB64-4228-B64E-EB430BCCE29E/project.app/project:
Address: project[0x00000002000fc970] (project.__TEXT.__text + 1027840)
Summary: project`static project.ViewControllerUtils.setRootViewController(storyboard: __C.UIStoryboard, withAnimation: Swift.Bool) -> () at ViewControllerUtils.swift:7
Module: file = "/Users/user/Library/Developer/CoreSimulator/Devices/DC7A5199-424E-4E38-A8A8-CB99C7D8CF82/data/Containers/Bundle/Application/BE7BB249-DB64-4228-B64E-EB430BCCE29E/project.app/project", arch = "x86_64"
CompileUnit: id = {0x00000000}, file = "/Users/user/mobile/company/iOS/project/project/Utils/ViewControllerUtils.swift", language = "swift"
Function: id = {0x7700000075}, name = "static project.ViewControllerUtils.setRootViewController(storyboard: __C.UIStoryboard, withAnimation: Swift.Bool) -> ()", mangled = "$S5project19ViewControllerUtilsC07setRootbC010storyboard13withAnimationySo12UIStoryboardC_SbtFZ", range = [0x000000010bd0c780-0x000000010bd0c82e)
FuncType: id = {0x7700000075}, byte-size = 8, decl = ViewControllerUtils.swift:7, compiler_type = "(UIKit.UIStoryboard, Swift.Bool) -> ()
"
Blocks: id = {0x7700000075}, range = [0x10bd0c780-0x10bd0c82e)
LineEntry: [0x000000010bd0c780-0x000000010bd0c79d): /Users/user/mobile/company/iOS/project/project/Utils/ViewControllerUtils.swift:7
Symbol: id = {0x00002a71}, range = [0x000000010ac0c780-0x000000010ac0c830), name="static project.ViewControllerUtils.setRootViewController(storyboard: __C.UIStoryboard, withAnimation: Swift.Bool) -> ()", mangled="$S5project19ViewControllerUtilsC07setRootbC010storyboard13withAnimationySo12UIStoryboardC_SbtFZ"
Variable: id = {0x6600000092}, name = "storyboard", type = "UIKit.UIStoryboard", location = DW_OP_fbreg(-16), decl = ViewControllerUtils.swift:7
Variable: id = {0x66000000a0}, name = "withAnimation", type = "Swift.Bool", location = DW_OP_fbreg(-24), decl = ViewControllerUtils.swift:7
Variable: id = {0x66000000ae}, name = "self", type = "#thick project.ViewControllerUtils.Type", location = DW_OP_fbreg(-32), decl = ViewControllerUtils.swift:7
Source code:
final class ViewControllerUtils {
static func setRootViewController(storyboard: UIStoryboard, withAnimation: Bool) {
setRootViewController(window: UIApplication.shared.keyWindow, storyboard: storyboard, withAnimation: withAnimation)
}
}
I know I could switch to Swift and invoke something like this:
expression -l swift -O -- ViewControllerUtils.setRootViewController(storyboard: UIKit.UIStoryboard(name: "Main", bundle: nil), withAnimation: true)
But I would like to learn how to invoke a function using its address or symbol without referencing to specific class like above.
I have found the solution.
Take address from range: Symbol: id = {0x00002a71}, range = [0x000000010ac0c780-0x000000010ac0c830) this one: 0x000000010ac0c780.
Import UIKit (lldb) po import UIKit
Create Storyboard:
(lldb) p UIStoryboard(name: "Main", bundle: nil)
(UIStoryboard) $R2 = 0x00006000006c8200 {
ObjectiveC.NSObject = {
isa = UIStoryboard
}
}
Cast raw address to function and invoke it using created Storyboard variable $R2:
(lldb) po unsafeBitCast(0x000000010ac0c780, to: (#convention(c)(UIKit.UIStoryboard, Bool) -> ()).self)($R2, true)
Here you can read also an interesting example of importing C function: Swift: How to call a C function loaded from a dylib

dlm package - Error in optim(parm, logLik, method = method, ...) : L-BFGS-B needs finite values of 'fn'

require(dlm)
start.vals = c(0,0,0)
names(start.vals) = c("lns2_obs", "lns2_alpha", "lns2_beta")
buildTVP <- function(parm, x.mat){
parm <- exp(parm)
return( dlmModReg(X=x.mat, dV=parm[1], dW=c(parm[2], parm[3])) )
}
TVP.mle = dlmMLE(y=k[,1], parm=start.vals, x.mat=k[,2], build=buildTVP, hessian=T)
in this code, k[,1] and k[,2] are 2 stocks prices. on TVP.mle line I got
Error in optim(parm, logLik, method = method, ...) : L-BFGS-B needs finite values of 'fn' " error.
k file link: https://drive.google.com/open?id=1scLaKRpSdmp-1T9qTp_5cEcBFnWKDAus
I could not find my mistake. Could you help me please?

How to get query parameters in Elm?

In my Elm program, I'd like to initialize my model based on the query string.
For example, if the query string is ?w=3&h=5 I'd like to have:
initialModel =
{ width = 3
, height = 5
}
Is that possible to achieve this in Elm, or the only way to do this is to get the query parameters in Javascript and pass them via a port?
Elm 0.19
For elm 0.19 the below concept is the same. Both of these packages still exist but have been moved and relabeled as the official elm/url and elm/browser libraries.
Elm 0.18
This example uses evancz/url-parser and elm-lang/navigation. There are a few kinks that aren't straightforward in the documentation, but I've explained them briefly below. The example should speak for itself.
module Main exposing (..)
import Html as H exposing (..)
import Navigation exposing (Location)
import UrlParser as UP exposing ((</>), (<?>), top, parsePath, oneOf, s, stringParam, Parser)
import Maybe.Extra as MaybeExtra exposing (unwrap)
type Route
= UrlRoute (Maybe String) (Maybe String)
| NotFoundRoute
type Msg
= UrlParser Navigation.Location
type alias Model =
{ location : Route
, w : String
, h : String
}
type alias SearchParams =
{ w : Maybe String, h : Maybe String }
main =
Navigation.program UrlParser
{ init = init
, view = view
, update = update
, subscriptions = (\_ -> Sub.none)
}
init : Location -> ( Model, Cmd Msg )
init location =
let
currentPath =
parseLocation location
in
( initialModel currentPath
, Cmd.none
)
parseLocation : Location -> Route
parseLocation location =
case (parsePath matchers location) of
Just route ->
route
Nothing ->
NotFoundRoute
matchers : Parser (Route -> a) a
matchers =
UP.map UrlRoute (UP.s "index" <?> UP.stringParam "w" <?> UP.stringParam "h")
initialModel : Route -> Model
initialModel route =
{ location = route
, w = MaybeExtra.unwrap "" (\x -> Maybe.withDefault "" x.w) (parseParams route)
, h = MaybeExtra.unwrap "" (\x -> Maybe.withDefault "" x.h) (parseParams route)
}
parseParams : Route -> Maybe SearchParams
parseParams route =
case route of
UrlRoute w h ->
Just { w = w, h = h }
NotFoundRoute ->
Nothing
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
UrlParser location ->
( model
, Cmd.none
)
view : Model -> Html msg
view model =
div []
[ h1 [] [ text "URL Info" ]
, div [] [ text ("W is: " ++ model.w) ]
, div [] [ text ("H is: " ++ model.h) ]
]
The "trick" is to create another type alias to place your query params inside of. In the above example I've created the type SearchParams. After creating this type we just use an initialModel that takes in the currentPath.
From there, our model can extract the query params with Maybe.withDefault (it needs to be a Maybe type because the params may not be there). Once we have our data in the model we just print it out in the view.
Hope this helps!
There is no built-in core library way to access the URL. You can use ports and the community library jessitron/elm-param-parsing.
If you also want to set the URL, you can again use ports, or you can use the History API, for which there are bindings in TheSeamau5/elm-history.
Unfortunately jessitron/elm-param-parsing doesn't work with Elm 0.18.
Use elm-lang/navigation package:
http://package.elm-lang.org/packages/elm-lang/navigation/latest/Navigation
https://github.com/elm-lang/navigation/tree/2.1.0
especially this function:
program
: (Location -> msg)
-> { init : Location -> (model, Cmd msg), update : msg -> model -> (model, Cmd msg), view : model -> Html msg, subscriptions : model -> Sub msg }
-> Program Never model msg
In the second parameter you can see "init : Location -> (model, Cmd msg)". This should handle reading of initial URL. To complement that, first parameter is a function which gets called every time URL changes.
(I am aware it's an old question, but this link popped out when I was looking for the solution to the same problem and accepted answer didn't help)

How to pass projects in order in FAKE

I need to build vb6 projects in order. How should I pass them to Vb6Make?
let projs = [
"a.vbp"
"b.vbp"
"c.vbp"
]
Target "VB6" (fun _ ->
!! projs // <- ?
|> Vb6Make
)
!! and ++ can be used for single files files as well. And FullName is important for directories.
let vb6dir = FullName "./bin"
let tempdir = FullName "./temp"
let projs =
!! "src\a\a.vbp"
++ "src\b\b.vbp"
++ "src\c\c.vbp"
Target "BuildVb6" (fun _ ->
projs
|> Fake.Vb6Helper.Vb6Make(fun c ->
{ c with
Logdir = tempdir
Outdir = vb6dir })
)