by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Oct 09 2019 10:41
    iboss-ptk synchronize #460
  • Oct 09 2019 10:21
    iboss-ptk edited #460
  • Oct 09 2019 10:21
    iboss-ptk edited #460
  • Oct 09 2019 10:20
    iboss-ptk opened #460
  • Oct 09 2019 09:58

    truizlop on utilities

    (compare)

  • Oct 09 2019 09:58

    truizlop on master

    Miscellaneous utilities (#459) … (compare)

  • Oct 09 2019 09:58
    truizlop closed #459
  • Oct 09 2019 07:53
    truizlop review_requested #459
  • Oct 09 2019 07:53
    truizlop review_requested #459
  • Oct 09 2019 07:53
    truizlop opened #459
  • Oct 09 2019 07:53

    truizlop on utilities

    Add docs (compare)

  • Oct 09 2019 07:52

    truizlop on utilities

    Fix wrong documentation Add instances of Semigroup and … Add utility to Kleisli and 2 more (compare)

  • Oct 09 2019 07:03
    truizlop commented #448
  • Oct 09 2019 01:34
    iboss-ptk commented #448
  • Oct 09 2019 01:28
    iboss-ptk commented #448
  • Oct 08 2019 10:42

    miguelangel-dev on calvellido-patch-1

    (compare)

  • Oct 08 2019 10:42

    miguelangel-dev on master

    Fix bad space char at docs (#45… (compare)

  • Oct 08 2019 10:42
    miguelangel-dev closed #458
  • Oct 08 2019 10:42
    miguelangel-dev commented #458
  • Oct 08 2019 10:39
    calvellido edited #458
Devesh Shetty
@devesh-shetty
Hey team,
Should Tuple * classes be part of bow core rather than optics? That way we could have it for bow and bow optics
Tomás Ruiz-López
@truizlop
Is there any functionality that you need to add for tuples in the core module?
Devesh Shetty
@devesh-shetty
Yes, Semigroupal’s product returns a Semigroupal<Tuple2>
Tomás Ruiz-López
@truizlop
That’s because Kotlin does not have language support for Tuples and they have to use that. We can return Kind<F, (A, B)> as the product result. In optics, we needed to create those Tuple* because tuples are not a nominal type in Swift and cannot therefore be extended to have computed properties or methods.
Devesh Shetty
@devesh-shetty
Yeah due to tuples not being nominal types, I can't do something like extension Tuple2: Equatable where A: Equatable, B: Equatable {}. I guess I could just compare those values.
Devesh Shetty
@devesh-shetty
Hi team,
Why are the functions map, extract, and coflatMap scoped to internal in Day? https://github.com/bow-swift/bow/blob/master/Sources/Bow/Data/Day.swift#L24-L30
Tomás Ruiz-López
@truizlop
Hi @devesh-shetty, the current implementation of Day is neither correct nor complete. These methods are internal and prepended with an underscore because they are meant to be implemented by internal subclasses of Day. The public ones come from the instance of Comonad for Day.
Devesh Shetty
@devesh-shetty
Ah, okay. I am working on porting these missing functions from arrow. bow-swift/bow#236
Will look into fixing existing implementation as well
Tomás Ruiz-López
@truizlop
that one is going to be a bit challenging, feel free to ask if you need help
BTW, yesterday we announced a cool side project: an Xcode extension that brings nef to your IDE. This initial version lets you generate a Carbon snippet image from a code selection without leaving Xcode. It is built with Bow and SwiftUI, available for macOS Catalina and Xcode 11 or above. If you help us promote it, it would be very nice: https://twitter.com/bow_swift/status/1188874856860794881?s=20
Devesh Shetty
@devesh-shetty
Oh cool that looks interesting!
Sébastien Drode
@Dragna
hello
I will try to recreate the architecture from the last videos of pointfree situ bow types and I would like to know what the best type to create a store would be.
the Moore type seems to be a good candidate with it’s handle method 🙂.
Tomás Ruiz-López
@truizlop
@Dragna I think you may need a combination of the Store and State data types, but I haven't looked exactly at how this can be implemented
if you achieve it with Moore I'd be interested in seen this approach
Sébastien Drode
@Dragna
the problem with Moore approach is that I need a wrapper class to keep the "state" it isn't keeping it internally so I need something else to act on the "instance" of Moore that I created.
I'll look at the combination of store and state to see what I can achieve.But if my understanding of those 2 types is right, the store let us act on a stored state, and the State let us expose a state (correct me if I'm wrong). the combination of both should be what I am looking for. I didn't think of combining both concepts together as one but this will be a great exercise 🙂 .
Thank you for your answer 🙂
Tomás Ruiz-López
@truizlop
no problem!
I guess at some point you will also need to introduce IO to handle effects as well
keep us updated with your progress and we can try to help
Sébastien Drode
@Dragna
Yep that's what I thought 🙂, I'll keep you updated for sure 🙂
Sébastien Drode
@Dragna

Hi everyone 👋
I have a little question, I'm in a case where I want to go from an IO<Error, MyModel?> to an IO<Never, MyModel?>
when I use the handleError method, I can return a nil, but the ErrorType doesn't switch to Never as I would suppose it should.
Using Apple Combine, the .replaceError method act like that.

am I missing something ?

func getPeopleAPI(id: Int) -> IO<Never, SWAPIPeopleResponse?> {
    var components = URLComponents(string: "https://swapi.co/api/people/\(id)")!


    return URLSession.shared
            .dataTaskIO(with: components.url(relativeTo: nil)!)
            .map { _, data in data }
            .map { data in
                try? JSONDecoder().decode(SWAPIPeopleResponse?.self, from: data)
            }
            .handleError({ _ in nil })^
}
Sébastien Drode
@Dragna
I know that in that case I should let the error pass, but I have a redux reducer that call this method. and I want to force my user to have reducers that never error out, in order to force them to implement error as a state of the feature.
Tomás Ruiz-López
@truizlop
Hi Sébastien, you can use mapLeft (which will be renamed to mapError in the next release) in order to change the error to Never.
Since it may not be "beautiful", you can create an extension method over IO that does handleError followed by mapError in order to have Never as the error type
Sébastien Drode
@Dragna
Thank you for your answer. that is what I tried, but do you know a way to return a Never ? 😛 because I found abort() but I don't know how it will react.
func getPeopleAPI(id: Int) -> IO<Never, SWAPIPeopleResponse?> {
    var components = URLComponents(string: "https://swapi.co/api/people/\(id)")!
    URLSession.shared.dataTaskPublisher(for: components.url(relativeTo: nil)!).replaceError(with: <#T##Output##Foundation.URLSession.DataTaskPublisher.Output#>)

    return  URLSession.shared
            .dataTaskIO(with: components.url(relativeTo: nil)!)
            .map { _, data in data }
            .map { data in
                try? JSONDecoder().decode(SWAPIPeopleResponse?.self, from: data)
            }
            .handleError({ _ in nil })^
            .mapLeft({ _ in abort() })
}
Miguel Ángel Díaz
@miguelangel-dev
Try with fatalError()
Usually is the way Apple uses to force a wrong path
but, it will break your app, but you are not using an EXIT (as abort is)
Tomás Ruiz-López
@truizlop
yes, we use fatalError() usually, although it is not recommended to be used in production code, that code should never be executed, it's just to make the compiler happy
(I see you are playing with the Star Wars API, cool!!!)
Miguel Ángel Díaz
@miguelangel-dev

on another hand, for me it is weird model your problem like an right-optional (maybe I am, and you want to wrap this network over IO)

you are working with: ERROR + (ERROR + VALUE) = ERROR + ERROR + VALUE, so you can go out with 2 possible errors (one from IO another for Optional - losing the type) - do you think about to change the API to: IO<ApiError, SWAPIPeopleResponse>

Sébastien Drode
@Dragna

@miguelangel-dev you are right, I shouldn't model it like that, for the network call, I should pass the error to the caller (that is what I will do at a later time) but I still need a way (that you 've given me) to go back to a Left Never, because in my redux implementation, I don't want the core implementation to know about errors, errors should be handled early (in the reducer part) to model it as a state published by the store.

I'll show you when I'm done with the whole implementation 🙂

I will change for a fatalError as suggested,

Thanks to you two for your help

Tomás Ruiz-López
@truizlop
you're welcome! keep us updated with your progress
Sébastien Drode
@Dragna
yes, will do
Miguel Ángel Díaz
@miguelangel-dev
:)
Marcelo Jasek
@marcjal
Hi 👋
Where I can find a project using this library?
Miguel Ángel Díaz
@miguelangel-dev

Hi Marcelo, it depends on kind the project you are looking for. For now, as OSS, we are working in a refactor in another library from bash to FP in pure Swift. It is nef: https://github.com/bow-swift/nef - and you can find the project using an architecture FP thanks to Bow: https://github.com/bow-swift/nef/tree/develop/project

It is nice because in the same project you can find an example how to make a functional-library (API) and how to use it (CLI) in pure Swift with Bow

if you open the nef tree-project you can find 4 modules: UI, Component, Core and Tests.
UI: examples Bow in CLI
Component: example of FP-architecture with Bow using Bow, BowEffects, BowOptics
Core: business logic and how to wrap into a FP architecture
Tomás Ruiz-López
@truizlop
Also, our project Bow OpenAPI is built using Bow and Bow Effects: https://github.com/bow-swift/bow-openapi
We are working towards providing more examples for macOS and iOS apps using FP and Bow. If you get something, let us know and we can link it as a reference in our documentation
Devesh Shetty
@devesh-shetty
Hi team,
Could I work on this? bow-swift/bow#286
Tomás Ruiz-López
@truizlop
Sure! I can assign it to you.
Devesh Shetty
@devesh-shetty
Awesome, thanks!
Sébastien Drode
@Dragna

hi everyone !

what would be the right way to execute an IO on background queue and get back to main queue to use the result ?

I tried

effect.attempt(on: .global(qos: .background)).unsafeRunAsync(on: .main,
                    { resultAction in
                        print(resultAction)
                        self.send(resultAction.rightValue) //Should never error out
                    })

but it seems to block the UIThread

Sébastien Drode
@Dragna
I tried with comprehensions too, but I think I'm missing something 🤔
            let action = IO<Never, Action>.var()
            let sendEffect = binding(
                continueOn(.global(qos: .userInitiated)),
                action <- effect,
                |<-ConsoleIO.print("action is \(action.get)"),
                continueOn(.main),
                |<-IO.invoke { self.send(action.get) },
                yield: ()
            )^
            try! sendEffect.unsafeRunSync()
Tomás Ruiz-López
@truizlop
The first code blocks because attempt is synchronous. Even though you are passing a different queue to run it, it will block the current queue until it finishes, and then do the unsafeRunAsync. The second one should work fine if you call sendEffect.unsafeRunAsync. It is the same reason: it blocks because it is synchronous.
Sébastien Drode
@Dragna
hmm even with unsafeRunAsync it's acting this way :/
public func send(_ action: Action) {
        let effects = self.reducer(&self.value, action)
        print(effects)
        effects.forEach { effect in
            let action = IO<Never, Action>.var()
            let sendEffect = binding(
                continueOn(.global(qos: .userInitiated)),
                action <- effect,
                |<-ConsoleIO.print("action is \(action.get)"),
                continueOn(.main),
                |<-IO.invoke { self.send(action.get) },
                yield: ()
            )^
            sendEffect.unsafeRunAsync({ _ in

            })
        }
    }
the send method is the method I use to send action to a redux Store, I want to execute the effects gotten from the reducer and execute the on background, get their result back and pass them to the .send method again
the problem is maybe elsewhere, I'll look