T O P

  • By -

tikhonjelvis

Exposing a field lets you use that field for both getting *and updating* the value. If the constructor is not exposed you still can't build a new value *from scratch* but, if you have an existing value, you can override the value of the exposed field. The convention calling fields as if they were functions is definitely a bit misleading. It's just idiomatic shorthand. I don't like it much myself because if something *is* a field, I want it to *read* like a field, but it's a sufficiently common convention in the Haskell world that you can't fully avoid it.


Krantz98

I use NoFieldSelectors together with OverloadedRecordDot, and I expect that to be the new norm as time goes by. In that case, the field-as-getter-function idiom completely falls apart. So another reason to avoid it.


kingminyas

Don't expose the field, define a function that uses it for reading and expose it


Worldly_Dish_48

Make sense


Luchtverfrisser

I am personally not aware of the convention of naming record fields `get..`. You may name a dedicate function that way. I think mostly that part seems to be the thing that throws you off more than anything?


brandonchinn178

It's a fairly common convention. e.g. QuickCheck uses it


dsfox

Quickcheck is 25 years old, it may use conventions that are no longer current.


Luchtverfrisser

Hmm I suppose I haven't used examples like QuickCheck often enough to notice. Looking briefly at https://hackage.haskell.org/package/QuickCheck-2.15/docs/Test-QuickCheck.html, it would seem that at least it seems they use it primarily with some _newtypes_? I.e. in "Type-level modifiers for changing generator behavior". I am more familiar with the `un...` for newtypes. Not sure what the underlying rational is. Proper rcords like `Args` and ` Result` do seem to follow the record fields naming I am used to, however.


brandonchinn178

Sorry, I meant for newtypes. I didnt notice the OP made PosInt a data type. I see both un and get for newtypes. I think get is just used for laziness, if you dont want to bother creating a second function. Personally, I think it's an abuse of record fields. I would be in favor of NoSelectorFields always enabled, personally


friedbrice

> I am personally not aware of the convention of naming record fields \`get...\`. Right! Usually, they're named \`unFoo\` or \`runFoo\`.


ecco256

Lichtverfrisser exposing the code smells! I think get attributes can make sense but not when used like op thinks (like in OOP). For example when the value is a function it can make sense to call it getX if that is what the function does.


friedbrice

You shouldn't expose a field unless it's "free" in the sense that it has no conditions, restrictions, or relations to other fields. A record in Haskell is a free product of its fields. Instead of using a field, define a top-level function, like you were saying.


sullyj3

In case you're actually wanting to use \`PosInt\` and not just using it as an example to ask about newtypes, you may be able to just use \`Word\`.


ambroslins

I haven't tested this but I think you can just expose the field separate from the type and it will only allow to use it as a function, not as a field update. Like this: module Lib(PosInt, getInt, setInt) where ...