Search code examples
haskellprotocol-buffershaskell-lens

Illegal term-level use of the type constructor / how to construct proto-lens generated objects?


How do I construct grpc generated data object, for example this https://github.com/search?q=repo%3Anickmi11er%2Ftinkoff-invest-haskell%20PortfolioRequest&type=code

defined on proto as

message PortfolioRequest {
  string account_id = 1;
}

I do try

let pr = PortfolioRequest (T.pack "0")

but getting Illegal term-level use of the type constructor error

it's using https://github.com/haskell-grpc-native/http2-grpc-haskell for generation, grpc-proto-lens, can't find examples how to actually construct objects of generated types

generated code looks like this:

{- | Fields :
     
         * 'Proto.Invest.Operations_Fields.accountId' @:: Lens' PortfolioRequest Data.Text.Text@ -}
data PortfolioRequest
  = PortfolioRequest'_constructor {_PortfolioRequest'accountId :: !Data.Text.Text,
                                   _PortfolioRequest'_unknownFields :: !Data.ProtoLens.FieldSet}
  deriving stock (Prelude.Eq, Prelude.Ord)
instance Prelude.Show PortfolioRequest where
  showsPrec _ __x __s
    = Prelude.showChar
        '{'
        (Prelude.showString
           (Data.ProtoLens.showMessageShort __x) (Prelude.showChar '}' __s))
instance Data.ProtoLens.Field.HasField PortfolioRequest "accountId" Data.Text.Text where
  fieldOf _
    = (Prelude..)
        (Lens.Family2.Unchecked.lens
           _PortfolioRequest'accountId
           (\ x__ y__ -> x__ {_PortfolioRequest'accountId = y__}))
        Prelude.id
instance Data.ProtoLens.Message PortfolioRequest where
  messageName _
    = Data.Text.pack
        "tinkoff.public.invest.api.contract.v1.PortfolioRequest"
  packedMessageDescriptor _
    = "\n\
      \\DLEPortfolioRequest\DC2\GS\n\
      \\n\
      \account_id\CAN\SOH \SOH(\tR\taccountId"
  packedFileDescriptor _ = packedFileDescriptor
  fieldsByTag
    = let
        accountId__field_descriptor
          = Data.ProtoLens.FieldDescriptor
              "account_id"
              (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
                 Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
              (Data.ProtoLens.PlainField
                 Data.ProtoLens.Optional
                 (Data.ProtoLens.Field.field @"accountId")) ::
              Data.ProtoLens.FieldDescriptor PortfolioRequest
      in
        Data.Map.fromList
          [(Data.ProtoLens.Tag 1, accountId__field_descriptor)]
  unknownFields
    = Lens.Family2.Unchecked.lens
        _PortfolioRequest'_unknownFields
        (\ x__ y__ -> x__ {_PortfolioRequest'_unknownFields = y__})
  defMessage
    = PortfolioRequest'_constructor
        {_PortfolioRequest'accountId = Data.ProtoLens.fieldDefault,
         _PortfolioRequest'_unknownFields = []}

Solution

  • The documentation isn't that hard to find from the code you posted: just Hoogle for Data.ProtoLens.Message and click around on a few promising links. It looks pretty clear how you're supposed to build a Message. In your example, you could write

    pr :: PortfolioRequest
    pr = build (accountId .~ T.pack "0")