witchcrafters / type_class

(Semi-)principled type classes for Elixir
https://hex.pm/packages/type_class
MIT License
140 stars 16 forks source link

[proposal] Make explicit that __MODULE__'s value changes when inside definst/3 #28

Closed toraritte closed 5 years ago

toraritte commented 5 years ago

Calling definst/3's body inside defimpl breaks the semantics of __MODULE__ (is this the proper way to say it?).

For example,

defmodule Name do
  import Algae
  import TypeClass
  use Witchcraft

  defdata do
    name :: String.t()
  end

  definst Witchcraft.Functor, for: __MODULE__ do
    @force_type_instance true

    def map(%__MODULE__{name: name}, f) do
      __MODULE__.new(name)
    end
  end
end

will result in

** (CompileError) lib/instance/assword.ex:13: 
Witchcraft.Functor.Proto.Instance.Name.__struct__/0 is undefined, 
cannot expand struct Witchcraft.Functor.Proto.Instance.Name

I know that map/2 above could've been defined as

def map(%{name: name}), do: Name.new(name)

or a long name could be aliased, but it is not intuitive, and I don't think this behaviour is documented. (That is, I remember some mention of it, but couldn't find that passage again.)


The two commits below are just suggestions:

icidasset commented 5 years ago

Thanks! I think this __MODULE__ stuff is breaking stuff in 1.9, this helps clear things up 👍