@@ -82,19 +82,6 @@ namespace purescript {
82 : std::shared_ptr<void>(std::make_shared<eff_fn_t>(f)) {
82 : std::shared_ptr<void>(std::make_shared<eff_fn_t>(f)) {
85− template <typename T,
86− typename = typename std::enable_if<!std::is_same<boxed,T>::value &&
87− std::is_convertible<T,fn_t>::value>::type>
88− auto operator=(const T& right) -> boxed& {
89− if (std::shared_ptr<void>::operator bool()) {
90− auto& f = *static_cast<fn_t*>(get());
93− reset(new fn_t(right));
98 auto operator()(const boxed& arg) const -> boxed {
85 auto operator()(const boxed& arg) const -> boxed {
99 auto& f = *static_cast<fn_t*>(get());
86 auto& f = *static_cast<fn_t*>(get());
100 return f(arg);
87 return f(arg);
@@ -133,6 +120,40 @@ namespace purescript {
134 }; // class boxed
121 }; // class boxed
123+ using fn_t = boxed::fn_t;
124+ using eff_fn_t = boxed::eff_fn_t;
125+ using dict_t = boxed::dict_t;
126+ using array_t = boxed::array_t;
128+ class boxed_r : private std::shared_ptr<void> {
130+ boxed_r() : std::shared_ptr<void>(std::make_shared<boxed>()) {}
132+ operator const boxed&() const {
133+ return *static_cast<const boxed*>(get());
136+ auto operator()(const boxed& arg) const -> boxed {
137+ auto& b = *static_cast<boxed*>(get());
138+ auto& f = *static_cast<fn_t*>(b.get());
142+ auto operator()() const -> boxed {
143+ auto& b = *static_cast<boxed*>(get());
144+ auto& f = *static_cast<eff_fn_t*>(b.get());
148+ template <typename T>
149+ auto operator=(T&& right) -> boxed_r& {
150+ auto& b = *static_cast<boxed*>(get());
151+ b = std::forward<T>(right);
136 template <typename T, typename... Args>
157 template <typename T, typename... Args>
137 inline auto box(Args&&... args) -> boxed {
158 inline auto box(Args&&... args) -> boxed {
138 return std::make_shared<T>(std::forward<Args>(args)...);
159 return std::make_shared<T>(std::forward<Args>(args)...);
@@ -163,11 +184,6 @@ namespace purescript {
163 return unbox<boxed::array_t>(a).size();
184 return unbox<boxed::array_t>(a).size();
166− using fn_t = boxed::fn_t;
167− using eff_fn_t = boxed::eff_fn_t;
168− using dict_t = boxed::dict_t;
169− using array_t = boxed::array_t;
171 constexpr auto undefined = nullptr;
187 constexpr auto undefined = nullptr;
173} // namespace purescript
189} // namespace purescript