search process by substring in his register name - process

In elixir, I can get the list of processes with their register name with
for pid <- Process.list, do: {pid, Process.info(pid, :registered_name)}
[
{#PID<0.0.0>, {:registered_name, :init}},
{#PID<0.1.0>, {:registered_name, :erts_code_purger}},
...
How can I get only the processes with a substring in their register name?
Example: get only the processes with the substring MyApp in their register name.

It’s better to do in a single pass with Enum.reduce/3
Enum.reduce(Process.list(), [], fn(pid), acc ->
with {:registered_name, name} = reg_name <- Process.info(pid, :registered_name),
true <- name |> to_string() |> String.contains?("proxy"),
do: [reg_name | acc],
else: (_ -> acc)
end)

Process.list
|> Enum.filter(fn(pid) ->
{:registered_name, name} = Process.info(pid, :registered_name)
to_string(name) =~ "MyApp"
end)
|> Enum.map(fn pid -> Process.info(pid, :registered_name) end)

Related

How to use interfaces with parameterized tuple?

I have Coord function that transforms an n-dimensional size to the type of coordinates bounded by given size: Coord [2,3] = (Fin 2, Fin 3).
import Data.Fin
import Data.List
Size : Type
Size = List Nat
Coord : Size -> Type
Coord [] = ()
Coord s#(_ :: _) = foldr1 (,) $ map Fin s
I'd like to use show and other functions like (==) with Coord s:
foo : Coord s -> String
foo x = show x
Error: While processing right hand side of foo. Can't find an implementation for Show (Coord s).
22 | foo : Coord s -> String
23 | foo x = show x
^^^^^^
Earlier I tried to implement Show (Coord s), but looks like it's impossible. Here is linked question about it.
You can make your own list like data type:
data Coords : List Nat -> Type where
Nil : Coords []
(::) : Fin x -> Coords xs -> Coords (x :: xs)
toList : Coords xs -> List Nat
toList [] = []
toList (x::xs) = finToNat x :: toList xs
example : Coords [2, 3]
example = [1, 2]
Show (Coords xs) where
show cs = show $ toList cs
You can also try using Data.Vect.Quantifiers.All or Data.List.Quantifiers.All:
import Data.Vect
import Data.Vect.Quantifiers
example : All Fin [1, 2, 3]
example = [0, 1, 2]
-- not sure why this is isn't included with Idris
export
All (Show . p) xs => Show (All p xs) where
show pxs = "[" ++ show' "" pxs ++ "]"
where
show' : String -> All (Show . p) xs' => All p xs' -> String
show' acc #{[]} [] = acc
show' acc #{[_]} [px] = acc ++ show px
show' acc #{_ :: _} (px :: pxs) = show' (acc ++ show px ++ ", ") pxs
string : String
string = show example

Why do I get an Unbound value Error even though it works in the Terminal in Ocaml

There has to be a minor error in my code because it works in the VSC-Terminal but not in the editor but I do not understand what it could be,
I get the Unbound value Error for the avg_grade and get_grades functions
Let studentlist be a list which safes student records. Each student has a (int*float) grades-list which safes a numeration as a int and the actual grades as floats.
My aim is to calculate the average grade of a single student with the function avg_grade.
I call the single student-record with the age with the get_student function.
type student = {
name : string;
age : int;
grades : (int*float) list;
}
let studentlist =
[ {name="alex"; age=7; grades=[(1,3.)]} ;
{name="bianca"; age=6; grades=[(1, 2.); (2, 3.)]} ]
(* main-function to calculate the average *)
let avg_grade a lst =
try
grades_sum a lst /. length a lst
with
Not_found -> 0.0
(* function to add all the float-grades,
it calls the list with get_grades *)
let grades_sum a lst =
List.fold_left (fun i (_,b) -> i +. b) 0. (get_grades a lst)
(* calls the grades of a single record which is called per age *)
let get_grades a lst =
(get_student a lst).grades
(*calls a single student-record*)
let get_student a lst =
List.find (fun {age;_} -> a = age) lst
(* computes the length of the given grades-list *)
let length a lst =
float_of_int (List.length (get_grades a lst))
You have this:
let avg_grade a lst = try grades_sum a lst /. length a lst with Not_found -> 0.0
But grades_sum isn't defined until after that line of code, so you get:
Error: Unbound value grades_sum
Additionally, a style suggestion. The |> operator may be useful for cleaning up some of your code. For better understanding of how it works:
let (|>) x f = f x
This allows something like f (g (h x)) to be written h x |> g |> f. Doing this lets us see that h x is being evaluated first. The result of that is sent to g, and then finally to f.
Both do the same thing, but the latter may be more expressive of what the code is doing.
You could use this to rewrite:
let length a lst =
float_of_int (List.length (get_grades a lst))
As:
let length a lst =
get_grades a lst |> List.length |> float_of_int

Partition list into more than 2 parts

So I want to partitision a List ItemModel in Elm into List (List ItemModel). List.partition only makes the list into two lists.
I wrote some code that makes the list into the parts I want (code below).
But it's not as nice of a solution as I'd like, and since it seems like an issue many people would have, I wonder are there better examples of doing this?
partition : List (ItemModel -> Bool) -> List ItemModel -> List (List ItemModel)
partition filters models =
let
filterMaybe =
List.head filters
in
case filterMaybe of
Just filter ->
let
part =
Tuple.first (List.partition filter models)
in
part :: (partition (List.drop 1 filters) models)
Nothing ->
[]
The returned list maps directly from the filters parameter, so it's actually pretty straightforward to do this using just List.map and List.filter (which is what you're really doing since you're discarding the remainder list returned from List.partition):
multifilter : List (a -> Bool) -> List a -> List (List a)
multifilter filters values =
filters |> List.map(\filter -> List.filter filter values)
Repeated partitioning needs to use the leftovers from each step as the input for the next step. This is different than simple repeated filtering of the same sequence by several filters.
In Haskell (which this question was initially tagged as, as well),
partitions :: [a -> Bool] -> [a] -> [[a]]
partitions preds xs = go preds xs
where
go [] xs = []
go (p:ps) xs = let { (a,b) = partition p xs } in (a : go ps b)
which is to say,
partitions preds xs = foldr g (const []) preds xs
where
g p r xs = let { (a,b) = partition p xs } in (a : r b)
or
-- mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
partitions preds xs = snd $ mapAccumL (\xs p -> partition (not . p) xs) xs preds
Testing:
> partitions [ (<5), (<10), const True ] [1..15]
[[1,2,3,4],[5,6,7,8,9],[10,11,12,13,14,15]]
unlike the repeated filtering,
> [ filter p xs | let xs = [1..15], p <- [ (<5), (<10), const True ]]
[[1,2,3,4],[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]]

Simplifying a two-parameter anonymous function in Elm

In Elm, if I have an anonymous function
(\f x -> f x)
I can simplify it to
(<|)
Can the same be done for a two-parameter function where the parameters are arguments to another function?
(\x y -> f x y |> g)
I thought I could simply use
(f |> g)
but the compiler complains about the types.
Specifically, in one of the cases for my update function, I have something like this:
let
msgNames = [Foo, Bar]
values = ["f", "b"] // These values are actually derived
// by a more complicated operation
model_ = List.map2 (<|) msgNames values
|> List.foldl (\msg mod -> update msg mod |> Tuple.first)
model
in
( model_, Cmd.none )
I am trying to simplify the anonymous function argument to List.foldl to something like (update |> Tuple.first), but I get the following error from the compiler:
The right side of (|>) is causing a type mismatch.
159| update |> Tuple.first)
^^^^^^^^^^^
(|>) is expecting the right side to be a:
(Msg -> Model -> ( Model, Cmd Msg )) -> a
But the right side is:
(( Model, Cmd Msg )) -> Model
We can follow a few steps to simplify:
(\x y -> f x y |> g)
... can be written as
(\x y -> g (f x y))
... can be written as
(\x -> g << f x)
One more step and things get a little more confusing:
(((<<) g) << f)
This matches what you get from pointfree.io (which is Haskell where function composition is done using the . operator):
(g .) . f
If you are trying to improve readability, you might just want to make your own infix function:
infixr 9 <<<
(<<<) : (c -> d) -> (a -> b -> c) -> (a -> b -> d)
(<<<) g f x y =
g (f x y)
And now you can use it like this:
(g <<< f)

Finding and replacing

There are times that we want to find an element in a list with a function a -> Bool and replace it using a function a -> a, this may result in a new list:
findr :: (a -> Bool) -> (a -> a) -> [a] -> Maybe [a]
findr _ _ [] = Nothing
findr p f (x:xs)
| p x = Just (f x : xs)
| otherwise = case findr p f xs of Just xs -> Just (x:xs)
_ -> Nothing
Is there any function in the main modules which is similar to this?
Edit: #gallais points out below that you end up only changing the first instance; I thought you were changing every instance.
This is done with break :: (a -> Bool) -> [a] -> ([a], [a]) which gives you the longest prefix which does not satisfy the predicate, followed by the rest of the list.
findr p f list = case break p list of
(xs, y : ys) -> Just (xs ++ f y : ys)
(_, []) -> Nothing
This function is, of course, map, as long as you can combine your predicate function and replacement function the right way.
findr check_f replace_f xs = map (replace_if_needed check_f replace_f) xs
replace_if_needed :: (a -> Bool) -> (a -> a) -> (a -> a)
replace_if_needed check_f replace_f = \x -> if check_f x then replace_f x else x
Now you can do things like findr isAplha toUpper "a123-bc".