Normalmente, nesse tipo de situação, você criaria um tipo de dados simples ou talvez um registro para agregar os diferentes campos:
data Displayable = Displayable Picture (Float,Float) (Float,Float) Float
As classes de tipo são para quando você precisa de um envio polimórfico para muitas implementações da mesma função. Esse certamente não é o caso de escala e posição, para o qual você terá apenas uma implementação. As dimensões podem ter formas diferentes de serem calculadas, como as dimensões naturais de um bitmap, mas essas diferenças quase certamente podem ser contabilizadas no momento da construção.
Você pode ter um caso para tornar toPicture
parte de uma classe de tipo, mas isso provavelmente pode ser tratado principalmente em tempo de construção, e então ter uma função que adiciona as transformações apropriadas sobre uma base Picture
apenas antes de renderizá-lo.
Outra possível estrutura de dados pode ser uma Picture
e uma lista de funções de transformação para aplicá-la:
data Displayable = Displayable Picture [Picture -> Picture]
Isso torna mais fácil adicionar novos tipos de transformações, como rotações ou até mesmo combinações complexas de transformações, mas torna mais difícil fazer operações como redefinir a escala de volta ao padrão. Talvez você possa adicionar uma descrição String
para cada transformação. Qual é o melhor vai depender do seu aplicativo. Meu ponto em incluir este exemplo é mostrar que o uso de campos de função pode impedir que você recorra a uma classe de tipos.
Não é que as classes de tipos não sejam úteis. Longe disso. É só que as situações em que criar uma nova é a melhor opção são relativamente raras. Quando você precisa criá-los, eles geralmente são muito pequenos e quase nunca mudam. Se você acha que pode precisar adicionar uma função a uma classe de tipo mais tarde, isso deve fazer você pensar duas vezes antes de usar uma.
Não há problema em ter muitas funções para manipular o tipo de dados de maneira mais amigável ao programador, mas você quer que elas estejam fora das classes de tipo, se possível. Toda vez que você adiciona uma função a uma classe de texto, você precisa adicioná-la a todas as instâncias.