Suppress Printing for Custom Structures in Julia - printing

I have a structure that ends up having a lot of circular references. It resembles this:
mutable struct Friend
a :: Int64
b :: Float64
your_best_friend :: Union{Nothing, Friend}
you_are_best_friend :: Union{Nothing, Friend}
Friend() = new()
end
Any two people who are best friends with each other will cause a circular reference when this is printed. Julia handles these circular references so that the print doesn't go forever, but I would prefer to have no printing at all whenever a variable of the structure Friend is created. I know supressor.jl is a thing, but I am wondering if there is a solution inherent to Base Julia. Basically, is there an option for structures so that the object isn't printed when assigned without using an extra package? If not, what's the next best thing? I am not a CS guy, so I'm not sure what kind of computation time printing takes, but I'd like to avoid it if possible (and I'm not sure supressor.jl removes the printing time or if printing still takes extra time but just isn't displayed). This seems simple to me, but I can't find the solution in the docs. Sorry if it is obvious and thanks in advance!
-J

You need to overload Base.show to change how objects are shown by the REPL:
julia> mutable struct Friend
a :: Int64
b :: Float64
your_best_friend :: Union{Nothing, Friend}
you_are_best_friend :: Union{Nothing, Friend}
Friend() = new()
end
julia> Friend()
Friend(0, 0.0, #undef, #undef)
julia> import Base.show
julia> show(io::IO, f::Friend) = show(io, "Friend $(f.a)")
show (generic function with 223 methods)
julia> d = Friend()
"Friend 0"
Note if you also want to change how things print outside the REPL command line, you may also need to overload printing via import Base.print

Related

List Cons-Into Function?

I am often wanting to take one list and cons every element into an existing list.
MyList = [3,2,1],
MyNewElements = [4,5,6],
MyNewList = lists:foldl(fun(A, B) -> [A | B] end, MyList, MyNewElements).
%% [6,5,4,3,2,1]
Assuming MyList has 1M elements and MyNewElements only has a few, I want to do this efficiently.
I couldn't figure out which of these functions- if any- did what I was trying to do:
https://www.erlang.org/doc/man/lists.html
Adding a short list to the beginning of a long list is cheap - the execution time of the ++ operator is proportional to the length of the first list. The first list is copied, and the second list is added as the tail without modification.
So in your example, that would be:
lists:reverse(MyNewElements) ++ MyList
(The execution time of lists:reverse/1 is also proportional to the length of the argument.)
Another option, aside from those already provided, would be just to have
NewDeepList = [MyList | DeepList]
and modify the reading/traversing to be able to handle [[element()]] instead of [element()].
Because erlang is function language and is different from c, javascript, it copy variable and modify it, not just modify it. Therefore it is impossible compression to o(A).length(A) is length of new added elements.

conversion data with erlang

my question now is :
I have the variavle M which contains : 37.5 (as you see is integer)
I want to convert M in order to be string "37.5"
so 37.5 should became "37.5"
I try with function :
M2=integer_to_list(M)
but when I execute this function it displays this error :
** exception error: bad argument
in function integer_to_list/1
called as integer_to_list(37.5)
integer_to_list wont work in that situation because 37.5 is a float and not an integer. Erlang does have float_to_list, but the output is usually pretty unusable.
Instead, I would recommend looking into mochiweb project for pretty conversion of floats to lists. In particular, the mochinum module:
> M = 37.5,
> mochinum:digits(M).
"37.5"
#chops has a great answer, IMO (using mochinum:digits/1), but you might also get something out of looking at the io_lib module. For example:
8> io_lib:format("~.2f",[37.5]).
["37.50"]
9> io_lib:format("~.1f",[37.5]).
["37.5"]
I realize this might not be exactly what you are looking for, and in this case I think looking at/using the mochinum module is an efficient way to go, but io_lib is often overlooked and provides a really useful set of functions for formatting lists / strings

Haskell 'else' parsing error

I'm having an parsing error on the input 'else' but I have no idea how to solve it. I'm still new to this haskell thing.
depot =
do
putStr ("Enter deposit amount: ")
deAmount <- getLine
let redeAmount = read deAmount
if redeAmount > 0 then
let accBal = redeAmount + accBal
else
putStrLn "Please enter amount greater than 0"
The first mistake is that the do (and everything after it) needs to be indented.
The next mistake is that syntactically let accBal = redeAmount + accBal can't stand on its own like that. Either it needs to be followed by an in or it must be directly inside a do block (being inside an if which is inside a do block does not count).
However even if you fix the syntax, it won't do what you want. You can't use let to reassign variables. As a matter of fact you can't reassign variables at all. If you fix the syntax of your let, it will simply create a new variable accBal which will shadow the old variable accBal. The scope of that new variable will be the then-block of the if. Once you leave the if-block, you'll accBal will again refer to the old value of accBal no matter what you did inside the if.
So to fix your issue, you need to restructure your logic, so it doesn't depend on accBal being reassigned.
I don't have much to add onto sepp2k's answer, but I thought I'd show you how I might write it:
type Balance = Float -- The type of the money balance
type TransactionT m a = StateT Balance m a -- Something that modifies a balance
type Transaction a = TransactionT IO a -- Something that interacts with IO
-- *and* modifies balance
-- Request the user to enter a deposit
getDeposit :: Transaction ()
getDeposit = do
putStr "Enter deposit amount: " -- You don't need () around the argument
amountStr <- liftIO getLine -- This is a consequence of using monad
-- transformers
let amount = read amountStr
if amount > 0
then modify (+ amount) -- Update the balance
else liftIO $ error "Please enter amount greater than 0." -- Raise an
-- exception
Here's a great little tutorial: http://learnyouahaskell.com/.
Here are some sections relevant to the code I wrote:
Let expressions
Case expressions
IO stuff
Functors
Monads
More Monads
Even More Monads
Oh, and to make your life easier, Hoogle.

Writing F# code to parse "2 + 2" into code

Extremely just-started-yesterday new to F#.
What I want: To write code that parses the string "2 + 2" into (using as an example code from the tutorial project) Expr.Add(Expr.Num 2, Expr.Num 2) for evaluation. Some help to at least point me in the right direction or tell me it's too complex for my first F# project. (This is how I learn things: By bashing my head against stuff that's hard)
What I have: My best guess at code to extract the numbers. Probably horribly off base. Also, a lack of clue.
let script = "2 + 2";
let rec scriptParse xs =
match xs with
| [] -> (double)0
| y::ys -> (double)y
let split = (script.Split([|' '|]))
let f x = (split[x]) // "This code is not a function and cannot be applied."
let list = [ for x in 0..script.Length -> f x ]
let result = scriptParse
Thanks.
The immediate issue that you're running into is that split is an array of strings. To access an element of this array, the syntax is split.[x], not split[x] (which would apply split to the singleton list [x], assuming it were a function).
Here are a few other issues:
Your definition of list is probably wrong: x ranges up to the length of script, not the length of the array split. If you want to convert an array or other sequence to a list you can just use List.ofSeq or Seq.toList instead of an explicit list comprehension [...].
Your "casts" to double are a bit odd - that's not the right syntax for performing conversions in F#, although it will work in this case. double is a function, so the parentheses are unnecessary and what you are doing is really calling double 0 and double y. You should just use 0.0 for the first case, and in the second case, it's unclear what you are converting from.
In general, it would probably be better to do a bit more design up front to decide what your overall strategy will be, since it's not clear to me that you'll be able to piece together a working parser based on your current approach. There are several well known techniques for writing a parser - are you trying to use a particular approach?

Creating a valid function declaration from a complex tuple/list structure

Is there a generic way, given a complex object in Erlang, to come up with a valid function declaration for it besides eyeballing it? I'm maintaining some code previously written by someone who was a big fan of giant structures, and it's proving to be error prone doing it manually.
I don't need to iterate the whole thing, just grab the top level, per se.
For example, I'm working on this right now -
[[["SIP",47,"2",46,"0"],32,"407",32,"Proxy Authentication Required","\r\n"],
[{'Via',
[{'via-parm',
{'sent-protocol',"SIP","2.0","UDP"},
{'sent-by',"172.20.10.5","5060"},
[{'via-branch',"z9hG4bKb561e4f03a40c4439ba375b2ac3c9f91.0"}]}]},
{'Via',
[{'via-parm',
{'sent-protocol',"SIP","2.0","UDP"},
{'sent-by',"172.20.10.15","5060"},
[{'via-branch',"12dee0b2f48309f40b7857b9c73be9ac"}]}]},
{'From',
{'from-spec',
{'name-addr',
[[]],
{'SIP-URI',
[{userinfo,{user,"003018CFE4EF"},[]}],
{hostport,"172.20.10.11",[]},
{'uri-parameters',[]},
[]}},
[{tag,"b7226ffa86c46af7bf6e32969ad16940"}]}},
{'To',
{'name-addr',
[[]],
{'SIP-URI',
[{userinfo,{user,"3966"},[]}],
{hostport,"172.20.10.11",[]},
{'uri-parameters',[]},
[]}},
[{tag,"a830c764"}]},
{'Call-ID',"90df0e4968c9a4545a009b1adf268605#172.20.10.15"},
{'CSeq',1358286,"SUBSCRIBE"},
["date",'HCOLON',
["Mon",44,32,["13",32,"Jun",32,"2011"],32,["17",58,"03",58,"55"],32,"GMT"]],
{'Contact',
[[{'name-addr',
[[]],
{'SIP-URI',
[{userinfo,{user,"3ComCallProcessor"},[]}],
{hostport,"172.20.10.11",[]},
{'uri-parameters',[]},
[]}},
[]],
[]]},
["expires",'HCOLON',3600],
["user-agent",'HCOLON',
["3Com",[]],
[['LWS',["VCX",[]]],
['LWS',["7210",[]]],
['LWS',["IP",[]]],
['LWS',["CallProcessor",[['SLASH',"v10.0.8"]]]]]],
["proxy-authenticate",'HCOLON',
["Digest",'LWS',
["realm",'EQUAL',['SWS',34,"3Com",34]],
[['COMMA',["domain",'EQUAL',['SWS',34,"3Com",34]]],
['COMMA',
["nonce",'EQUAL',
['SWS',34,"btbvbsbzbBbAbwbybvbxbCbtbzbubqbubsbqbtbsbqbtbxbCbxbsbybs",
34]]],
['COMMA',["stale",'EQUAL',"FALSE"]],
['COMMA',["algorithm",'EQUAL',"MD5"]]]]],
{'Content-Length',0}],
"\r\n",
["\n"]]
Maybe https://github.com/etrepum/kvc
I noticed your clarifying comment. I'd prefer to add a comment myself, but don't have enough karma. Anyway, the trick I use for that is to experiment in the shell. I'll iterate a pattern against a sample data structure until I've found the simplest form. You can use the _ match-all variable. I use an erlang shell inside an emacs shell window.
First, bind a sample to a variable:
A = [{a,b},[{c,d}, {e,f}]].
Now set the original structure against the variable:
[{a,b},[{c,d},{e,f}]] = A.
If you hit enter, you'll see they match. Hit alt-p (forget what emacs calls alt, but it's alt on my keyboard) to bring back the previous line. Replace some tuple or list item with an underscore:
[_,[{c,d},{e,f}]].
Hit enter to make sure you did it right and they still match. This example is trivial, but for deeply nested, multiline structures it's trickier, so it's handy to be able to just quickly match to test. Sometimes you'll want to try to guess at whole huge swaths, like using an underscore to match a tuple list inside a tuple that's the third element of a list. If you place it right, you can match the whole thing at once, but it's easy to misread it.
Anyway, repeat to explore the essential shape of the structure and place real variables where you want to pull out values:
[_, [_, _]] = A.
[_, _] = A.
[_, MyTupleList] = A. %% let's grab this tuple list
[{MyAtom,b}, [{c,d}, MyTuple]] = A. %% or maybe we want this atom and tuple
That's how I efficiently dissect and pattern match complex data structures.
However, I don't know what you're doing. I'd be inclined to have a wrapper function that uses KVC to pull out exactly what you need and then distributes to helper functions from there for each type of structure.
If I understand you correctly you want to pattern match some large datastructures of unknown formatting.
Example:
Input: {a, b} {a,b,c,d} {a,[],{},{b,c}}
function({A, B}) -> do_something;
function({A, B, C, D}) when is_atom(B) -> do_something_else;
function({A, B, C, D}) when is_list(B) -> more_doing.
The generic answer is of course that it is undecidable from just data to know how to categorize that data.
First you should probably be aware of iolists. They are created by functions such as io_lib:format/2 and in many other places in the code.
One example is that
[["SIP",47,"2",46,"0"],32,"407",32,"Proxy Authentication Required","\r\n"]
will print as
SIP/2.0 407 Proxy Authentication Required
So, I'd start with flattening all those lists, using a function such as
flatten_io(List) when is_list(List) ->
Flat = lists:map(fun flatten_io/1, List),
maybe_flatten(Flat);
flatten_io(Tuple) when is_tuple(Tuple) ->
list_to_tuple([flatten_io(Element) || Element <- tuple_to_list(Tuple)];
flatten_io(Other) -> Other.
maybe_flatten(L) when is_list(L) ->
case lists:all(fun(Ch) when Ch > 0 andalso Ch < 256 -> true;
(List) when is_list(List) ->
lists:all(fun(X) -> X > 0 andalso X < 256 end, List);
(_) -> false
end, L) of
true -> lists:flatten(L);
false -> L
end.
(Caveat: completely untested and quite inefficient. Will also crash for inproper lists, but you shouldn't have those in your data structures anyway.)
On second thought, I can't help you. Any data structure that uses the atom 'COMMA' for a comma in a string should be taken out and shot.
You should be able to flatten those things as well and start to get a view of what you are looking at.
I know that this is not a complete answer. Hope it helps.
Its hard to recommend something for handling this.
Transforming all the structures in a more sane and also more minimal format looks like its worth it. This depends mainly on the similarities in these structures.
Rather than having a special function for each of the 100 there must be some automatic reformatting that can be done, maybe even put the parts in records.
Once you have records its much easier to write functions for it since you don't need to know the actual number of elements in the record. More important: your code won't break when the number of elements changes.
To summarize: make a barrier between your code and the insanity of these structures by somehow sanitizing them by the most generic code possible. It will be probably a mix of generic reformatting with structure speicific stuff.
As an example already visible in this struct: the 'name-addr' tuples look like they have a uniform structure. So you can recurse over your structures (over all elements of tuples and lists) and match for "things" that have a common structure like 'name-addr' and replace these with nice records.
In order to help you eyeballing you can write yourself helper functions along this example:
eyeball(List) when is_list(List) ->
io:format("List with length ~b\n", [length(List)]);
eyeball(Tuple) when is_tuple(Tuple) ->
io:format("Tuple with ~b elements\n", [tuple_size(Tuple)]).
So you would get output like this:
2> eyeball({a,b,c}).
Tuple with 3 elements
ok
3> eyeball([a,b,c]).
List with length 3
ok
expansion of this in a useful tool for your use is left as an exercise. You could handle multiple levels by recursing over the elements and indenting the output.
Use pattern matching and functions that work on lists to extract only what you need.
Look at http://www.erlang.org/doc/man/lists.html:
keyfind, keyreplace, L = [H|T], ...

Resources