venezuela unisubjetivos tipos tipo subjetivo penales materia los funcion ejemplos delitos delito comunes como clasificacion cerrados califica abiertos functional-programming d typeclass

functional-programming - unisubjetivos - tipos de delitos en venezuela



¿Se pueden usar los rasgos en D para las clases de tipo? (3)

Soy nuevo en D, y estoy buscando una buena manera de programar con clases tipo Haskell, por ejemplo, Functors, Monoids, etc.

¿Se implementa algo así en Tango o Phobos?

He escuchado acerca de rasgos que permiten la verificación de tipos en tiempo de compilación para ciertas propiedades. ¿Se pueden utilizar para clases de tipo?

He intentado un poco con la especialización de plantillas y he encontrado esto:

// Monoid.d // generic Monoid gets called when there is no instance of Monoid for Type T class Monoid(T) { pragma(msg, "Type is not a Monoid"); } // Monoid instance for double class Monoid(T:double) { static T mzero() { return 0; } static T mappend(T a, T b ) { return a + b;} } // Monoid instance for int class Monoid(T:int) { static T mzero() { return 0; } static T mappend(T a, T b ) { return a + b;} }

Un algoritmo genérico cuyo parámetro de tipo debe ser un Monoide podría expresarse como:

template genericfunctions() { T TestMonoid(T,N = Monoid!T)(T a) { return N.mappend(N.mzero(),a); } }

Sin embargo, si desea omitir los parámetros de la plantilla, debe importar todas las instancias de genericfunctions necesarias y genericfunctions plantilla de genericfunctions .

import Monoid; import std.stdio; import std.conv; mixin genericfunctions; void main() { writefln(to!string(TestMonoid(3))); writefln(to!string(TestMonoid(3.3243))); }

Ahora puedes usar ints y dobles como Monoides.

Sin embargo, las cosas se vuelven más complejas cuando tienes una clase de tipo como Functor cuyas instancias son genéricas:

module Functors; // generic Functor like generic Monoid class Functor(alias T, A) { pragma(msg,"Not an instance of Functor"); } // very simple container to demonstrate functors behavior class FunctorTest(A) { public A a; this(A a) { this.a = a; } } // instance of Functor for FunctorTest!A class Functor(alias T:FunctorTest,A) { static T!B fmap(B)(T!A a, B delegate(A) fn) { return new T!B(fn(a.a)); } }

Un algoritmo se vería así:

template genericfunctions() { T TestMonoid(T,N = Monoid!T)(T a) { return N.mappend(N.mzero(),a); } // F is the Functor, A the functors type before, // B the functors Type after, N is the instance of Functor F!B fmap(alias F,A,B,N=Functor!(F,A))(F!A a, B delegate(A) fn) { return N.fmap!B(a,fn); } }

Afortunadamente, puedes omitir los cuatro parámetros de la plantilla cuando lo uses:

mixin genericfunctions; void main() { auto a = new FunctorTest!int(3); auto b = fmap(a,(int b) {return b+ 0.5;}); writefln(to!string(b.a)); }

Pero cuando quiere usar otra instancia de Functor para el Tipo, tiene que especificar los 4 parámetros de tipo de fmap. ¿Hay alguna forma en la que solo necesite especificar la instancia y los otros parámetros podrían deducirse de esto?

¿Hay alguna alternativa a la torpe combinación de soluciones?

¿Hay otras desventajas de este enfoque que no veo?

¿Qué hay de otras maneras?

Gracias por leer hasta aquí y por tomarse el tiempo para pensar y responder :)

Editar:

¿Es posible definir restricciones como las leyes de functor con unittest en D? Eso seria muy bueno.


¿Es posible definir restricciones como las leyes de functor con unittest en D? Eso seria muy bueno.

Phobos tiene otro concepto en la parte superior del lenguaje, como lo serían los monoides, los funtores y las mónadas. Y eso es Ranges . Ahora la forma en que Phobos está verificando si un tipo es un rango es mediante la definición de una plantilla que verifica si ciertas funciones pueden ser llamadas en un tipo. Si estas funciones son genéricas en sí mismas, la respuesta de la plantilla dependerá de que el compilador pueda encontrar un método que coincida con su tipo.

Para refenrence, aquí está la comprobación de tipo para un ForwardRange (los puntos de enlace al código con más documentos):

template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); }

Con eso puedes crear una restricción de plantilla así:

template isFunctor(Testant) { enum bool isFunctor = is(typeof( () { Testant t = Testant.init; // can instantiate that type auto result = t.fmap((Testant){}); // can call fmap on it with the type as parameter. } }

Tenga en cuenta que el UFCS con fmap arriba, fmap aún coincide con su decalaración.

También tenga en cuenta que podría ser mejor usar estructuras en lugar de clases. Ya que son tipos de valor y podemos tener Compile Time Function Execution (CTFE) en D, con un uso inteligente de opCall, puede usarlos como si fueran funciones en sí mismas.


En lugar de responder a tu pregunta, ya que eso requeriría entender lo que has dicho. Solo voy a divagar sobre las características de D que está utilizando y las que podrían serle de utilidad.

D no tiene clases de tipo (como sabes). En su lugar, tiene especialización de tipo (que está utilizando) y restricciones de plantilla . La especialización de tipo vino antes de las restricciones de plantilla y, de hecho, puede usarse allí.

Una restricción de plantilla le permite requerir ciertas propiedades de un tipo. Encontrará que esto se usa mucho en std.range y hay plantillas que ayudan a escribir tales restricciones en std.traits. Puedo hacer un ejemplo más complicado, pero por ahora, esto acepta tipos que se convierten a int:

void myFunction(T)(T param) if(is(T:int)) { }


template genericfunctions() { T TestMonoid(T,N = Monoid!T)(T a) { return N.mappend(N.mzero(),a); } }

No hay necesidad de eso:

T TestMonoid(T,N = Monoid!T)(T a) { return N.mappend(N.mzero(),a); }

Eso debería ser suficiente. Con esto, tampoco hay necesidad de la mixin .

¿Es posible definir restricciones como las leyes de functor con unittest en D?

No estoy completamente seguro de que entiendo lo que está pidiendo, pero puede definir restricciones con funciones / clases de plantillas:

void isEven(T)(T x) if (isIntegral!T) { return x % 2 == 0; }

Esta plantilla solo creará una instancia si T es un tipo integral.

Consulte la sección ''Restricciones de plantillas'' en la parte inferior de la página Templates .