# Coercible types constructors discrepancy

**URL:** <https://discourse.dry-rb.org/t/coercible-types-constructors-discrepancy/983>\
**Category:** dry-types\
**Created:** [January 17, 2020, 10:09am UTC](https://discourse.dry-rb.org/t/coercible-types-constructors-discrepancy/983 "2020-01-17T10:09:00Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![DawidJanczak](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/dawidjanczak/32/261_2.png) [@DawidJanczak](https://discourse.dry-rb.org/u/DawidJanczak)\
**Post date:** [January 17, 2020, 10:09am UTC](https://discourse.dry-rb.org/t/coercible-types-constructors-discrepancy/983/1 "2020-01-17T10:09:00Z")

</div>

Hello,

There seems to be a small discrepancy in how constructors work. My schema always gets arrays as values, even if they have only one element. In some cases I want to grab the first element of an array and coerce it to a type. In any case the type I’m using to extract the first element from an array as a stringified bool looks like this `Types::Params::Bool.constructor(&:first)` and works just fine:

```auto
[21] pry(main)> Types::Params::Bool.constructor(&:first).call(['false'])
=> false
[22] pry(main)> Types::Params::Bool.constructor(&:first).call(['ffalse'])
Dry::Types::CoercionError: ffalse cannot be coerced to false

```

However the same thing with date doesn’t work:

```auto
[20] pry(main)> Types::Params::Date.constructor(&:first).call(['2019-01-05'])
Dry::Types::CoercionError: ["2019-01-05"] is not a string
from /usr/local/bundle/gems/dry-types-1.2.2/lib/dry/types/coercions.rb:47:in `to_date'

```

Not sure if I’m doing something wrong 🙂

---

<div class="post-metadata">

**Author:** ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)\
**Post date:** [January 17, 2020, 10:44am UTC](https://discourse.dry-rb.org/t/coercible-types-constructors-discrepancy/983/2 "2020-01-17T10:44:50Z")

</div>

@DawidJanczak this is expected although I’m not suprised it confused you - `Types::Params::*` **are constructor types** , so their coercion logic is applied before yours. This means you need to prepend your logic:

```ruby
[3] pry(main)> Types::Params::Date.prepend(&:first).call(['2019-01-05'])
=> #<Date: 2019-01-05 ((2458489j,0s,0n),+0s,2299161j)>

```

I’m not sure why it worked for `Bool` but it _could be a bug_. I’d have to debug it.

---

<div class="post-metadata">

**Author:** ![DawidJanczak](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/dawidjanczak/32/261_2.png) [@DawidJanczak](https://discourse.dry-rb.org/u/DawidJanczak)\
**Post date:** [January 20, 2020, 2:19am UTC](https://discourse.dry-rb.org/t/coercible-types-constructors-discrepancy/983/3 "2020-01-20T02:19:53Z")

</div>

Thank you @solnic, that works! Piggybacking on that how do I handle invalid dates in those situations? Suppose I use the type you defined above in a `params` block in a schema like so:

```auto
MyDateConstructor = Types::Params::Date.prepend(&:first)
optional(:date).filter(size?: 1).value(MyDateConstructor)

```

when provided with invalid date the schema fails with `Dry::Types::CoercionError: invalid date` on an input like `date: %w[2019-08-FO]`. Should I be handling that myself with the mechanism described here [https://github.com/dry-rb/dry-types/blob/master/CHANGELOG.md#added-4](https://github.com/dry-rb/dry-types/blob/master/CHANGELOG.md#added-4) or is there another way to approach this?

Also I tried to do the same for `Bool` (`Types::Params::Bool.prepend(&:first)`) and that fails with `undefined method `prepend’ for #Dry::Types::Sum:0x000055aa4531d630` Perhaps that’s where the discrepancy is coming from?

Similar thing happens with String: `Types::String.prepend(&:first)` throws `undefined method `prepend' for #<Dry::Types[Constrained<Nominal<String> rule=[type?(String)]>]>`

---

<div class="post-metadata">

**Author:** ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)\
**Post date:** [January 20, 2020, 6:22pm UTC](https://discourse.dry-rb.org/t/coercible-types-constructors-discrepancy/983/4 "2020-01-20T18:22:18Z")

</div>

> when provided with invalid date the schema fails with `Dry::Types::CoercionError: invalid `

Unfortunately you hit a bug. I just reported an issue about: [lax on a prepended constructor still raises · Issue #387 · dry-rb/dry-types · GitHub](https://github.com/dry-rb/dry-types/issues/387)

---

<div class="post-metadata">

**Author:** ![DawidJanczak](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/dawidjanczak/32/261_2.png) [@DawidJanczak](https://discourse.dry-rb.org/u/DawidJanczak)\
**Post date:** [January 21, 2020, 1:53am UTC](https://discourse.dry-rb.org/t/coercible-types-constructors-discrepancy/983/5 "2020-01-21T01:53:58Z")

</div>

Thank you! Are the `Bool` and `String` examples different bugs as well or something else entirely?

---

<div class="post-metadata">

**Author:** ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)\
**Post date:** [January 21, 2020, 10:23am UTC](https://discourse.dry-rb.org/t/coercible-types-constructors-discrepancy/983/6 "2020-01-21T10:23:49Z")

</div>

@DawidJanczak it was the same bug. Nikita already fixed it. It will work fine in `1.3.0` - expect a release soon.

---

<div class="post-metadata">

**Author:** ![DawidJanczak](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/dawidjanczak/32/261_2.png) [@DawidJanczak](https://discourse.dry-rb.org/u/DawidJanczak)\
**Post date:** [January 21, 2020, 11:01am UTC](https://discourse.dry-rb.org/t/coercible-types-constructors-discrepancy/983/7 "2020-01-21T11:01:17Z")

</div>

Awesome, thank you 🙂
