VegOwOtenks

joined 10 months ago
[–] [email protected] 2 points 50 minutes ago

Unfortunately not :/ But I do have rainbow-gradient window borders.

[–] [email protected] 3 points 5 hours ago (1 children)

I suppose you're mainly concerned about LibAdwaita-Apps?

[–] [email protected] 4 points 5 hours ago

I was surprised to learn that

  • a) macOS only recently added Left/Right-tiling natively (without extensions, just like GNOME does)
  • b) they leave gaps when you tile them so that it looks like you messed up the tiling somehow
 
[–] [email protected] 0 points 1 month ago

Thank you for the detailed answer, especially the explanation 'in more words' and the link helped me understand what happens in this Monoid instance.

 

I consider myself to be learning haskell. I am proficient enough to solve Advent of Code and do some small projects using it. I love doing it but I always feel like there's more to it. Apparently there is: this blog post from Reasonably Polymorphic caught me, I was probably exactly the intended audience.

What's in the blog post?

They visualize the Builder Pattern, where an Object is created through repeated mutation, which, when transferred to Haskell, should be replaced by creating objects through Monoids and the corresponding Semigroup function <>.

I parse a programming language using parsec and I did exactly what was proposed to enhance my structure creation.

Before, my code was this

Old Code

data StructStatement = Variable VariableName VariableType
        | Function Function.Function

data Struct = Struct 
        { name :: String
        , variables :: [(VariableName, VariableType)]
        , functions :: [Function]
        }
        deriving (Show)

addVariable :: Struct -> VariableName -> VariableType -> Struct
addVariable (Struct sn vs fs) n t = Struct sn ((n, t): vs) fs

addFunction :: Struct -> Function -> Struct
addFunction (Struct sn vs fs) f = Struct sn vs (f:fs)

accumulateStruct :: Struct -> StructStatement -> Struct
accumulateStruct s (Variable n t) = addVariable s n t
accumulateStruct s (Function f)   = addFunction s f

Then using a fold over Struct _ [] [] (which is basically mempty I just realized) would get me the complete struct. It is kind of ugly:

foldl accumulateStruct (Struct structIdentifier [] []) <$!> braces (many structMember)

Now my code is this

New Code

data Struct = Struct
        { name :: String
        , body :: StructBody
        }
        deriving (Show)

data StructBody = StructBody
        { variables :: [(VariableName, VariableType)]
        , functions :: [Function]
        }
        deriving stock (Generic, Show)
        deriving (Semigroup, Monoid) via StructBody

Which shorter and easier to use, the entire construction only looks like this now:

mconcat <$!> UbcLanguage.braces (many structMember)

I love the new construction method using Semigroup and Monoid. However, I don't understand them in depth anymore. I have written my own instance of Semigroup and Monoid, and I assume these deriving clauses do something similar.

Handwritten Semigroup instance

instance Semigroup StructBody where
  (<>) s1 s2 = StructBody
        { variables = variables s1 <> variables s2
        , functions = functions s1 <> functions s2
        }

Monoid instance is trivial then, just default all the values to mempty.

I also have a dump of the generated class instances using -ddump-deriv -dsuppress-all:

Generated instances

instance Semigroup StructBody where
  (<>) :: StructBody -> StructBody -> StructBody
  sconcat :: NonEmpty StructBody -> StructBody
  stimes ::
    forall (b_a87f :: *). Integral b_a87f =>
                          b_a87f -> StructBody -> StructBody
  (<>)
    = coerce
        @(Generically StructBody
          -> Generically StructBody -> Generically StructBody)
        @(StructBody -> StructBody -> StructBody)
        ((<>) @(Generically StructBody))
  sconcat
    = coerce
        @(NonEmpty (Generically StructBody) -> Generically StructBody)
        @(NonEmpty StructBody -> StructBody)
        (sconcat @(Generically StructBody))
  stimes
    = coerce
        @(b_a87f -> Generically StructBody -> Generically StructBody)
        @(b_a87f -> StructBody -> StructBody)
        (stimes @(Generically StructBody))

instance Monoid StructBody where
  mempty :: StructBody
  mappend :: StructBody -> StructBody -> StructBody
  mconcat :: [StructBody] -> StructBody
  mempty
    = coerce
        @(Generically StructBody) @StructBody
        (mempty @(Generically StructBody))
  mappend
    = coerce
        @(Generically StructBody
          -> Generically StructBody -> Generically StructBody)
        @(StructBody -> StructBody -> StructBody)
        (mappend @(Generically StructBody))
  mconcat
    = coerce
        @([Generically StructBody] -> Generically StructBody)
        @([StructBody] -> StructBody) (mconcat @(Generically StructBody))

In the documentation it says that there is an instance (Generic a, Monoid (Rep a ())) => Monoid (Generically a) which is defined exactly like the generated instance ghc dumped (source) which uses the Monoid of (Rep a ()) which isn't defined anywhere.

Where does the monoid come from? This is the generated type Rep

GeneratedDerived type family instances: type Rep StructBody = D1 ('MetaData "StructBody" "Ubc.Parse.Syntax.Struct" "main" 'False) (C1 ('MetaCons "StructBody" 'PrefixI 'True) (S1 ('MetaSel ('Just "variables") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [(VariableName, VariableType)]) :*: S1 ('MetaSel ('Just "functions") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [Function])))
but I cannot find a Monoid instance. Do you know where I could learn about this?

Thank you for your time and attention

[–] [email protected] 3 points 2 months ago

Thanks a lot for the recommendation, I did enjoy the read!

[–] [email protected] 2 points 3 months ago (2 children)

I was wondering about encryption (is this what you're talking about?) because these algorithms change so frequently I'd be surprised if they had anything back then considered 'secure' by now.

 

I mean the Voyager 1 probe which is currently the human-made object the farthest away from earth. The space program people operating the mission seem to have great control options, they even "moved software from one chip to another" (link) Apart from the probably gigantic and expensive installation needed to receive and/or send messages from/to that far away from home (23 hours of delay?), are there any safety measures to prevent a potentially malicous actor from sending commands to the probe?

 

Up until now I simply used Element, it just works and it doesn't look too bad. Unfortunately, I now have two Matrix accounts, my personal account and the account my university automatically created on their own matrix instance.
I need to communicate using both my accounts now, but Element couldn't handle two accounts at the same time, so I went on to install a second client, Fractal, which also supports multiple accounts. However, I am somewhat unhappy with Fractal because I cannot select text in messages.

Please share your experiences and recommendations with or on matrix clients.

 
 
[–] [email protected] 1 points 6 months ago (1 children)

You could wrap the entirety of your file in a monster macro but you'd still have to assign the macro result to a variable you need to register, which doesn't sound viable to me at least.

Maybe you can use a script that would extract all the trait implementations and create the boilerplate glue code for you, something like this:

grep --recursive --only-matching "impl PluginFunction for \w*" functions/ | sed --quiet "s/functions\/\(.*\)\.rs:impl PluginFunction for \(\w*\)/crate::functions::\1::\2{}.register(\&mut functions_map)/p"

I tried to recreate your situation locally but it may not match perfectly, maybe you'll have to adjust it a little. When I run it on my file tree which looks like this

functions
├── attr.rs
├── export.rs
└── render.rs

1 directory, 3 files

where every file has a content like this

// comment

pub struct MyAttrStructName {}

impl PluginFunction for MyAttrStructName {

}

Then I receive the following output:

crate::functions::attr::MyAttrStructName{}.register(&mut functions_map)
crate::functions::export::MyExportStructName{}.register(&mut functions_map)
crate::functions::render::MyRenderStructName{}.register(&mut functions_map)
 
 
[–] [email protected] 1 points 9 months ago

You can, another comment mentioned that. Only, I didn't mean to spread misinformation because I haven't used anything else in years.

[–] [email protected] 5 points 9 months ago

I feel this, I like to see my wallpaper

[–] [email protected] 21 points 9 months ago (8 children)

I was amazed to find out you can open a new tab by using middle-click in firefox.

[–] [email protected] 6 points 9 months ago

Fair point. My browser (FF) supports 'search in tabs' as well and suggest it over a new search engine result when typed in the address bar. I don't know what about the style makes me think this, but it looks like FF on Windows in the Screenshot.

 
 
[–] [email protected] 4 points 10 months ago

Love seeing a GNOME rice, I tried some GNOME ricing on a Fedora myself, however I was unable to get any further than installing Extensions 'Just Perfection' to hide some elements or using 'Burn my Windows', which I loved.

What did you use to style your GNOME-Shell Components?

view more: next ›