lukaswilkeer / SignatureTester

Teste via assinatura da funcão

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Signature Tester

Essa ideia iniciou-se em uma madrugada, trocando ideia sobre testes com o Lukas, um grande colaborador da Webschool na área da Matemática, e em algum momento começamos a falar sobre as assinatura das funções pois eu sempre quis "documentar" minhas funções usando aquela nomenclatura sapeca da Matemática que sempre vejo nos projetos de Programação Funcional.


Se você não sabe o que é a assinatura de um método eu irei sanar-lhe essa dúvida.


Vamos ver o que a Wikipedia nos diz:

A function signature consists of the function prototype. It specifies the general information about a function like the name, scope and parameters.

fonte: https://en.wikipedia.org/wiki/Type_signature

Vamos analisar essa assinatura abaixo:


f :: a -> b -> c


Nela temos uma função f que receberá um tipo a, ela retornará outra função a qual tem a entrada do tipo b e que retornará o c, traduzindo para JavaScript podemos escrever assim:

const f = ( a ) => ( b ) => c

Por exemplo:


const f = ( a ) => {
  const b = a.age  
  return ( b ) => b >= 18
}

const b = f( {age: 32} )
const c = b(32)

console.log(c)
true


Como na assinatura que analisamos anteriormente a função f recebeu um parâmetro a, do tipo Object e retornou outra função. Essa recebe um parâmetro b, do tipo Number e irá retornar em c um valor Boolean, para testar se a idade é maior ou igual a 18.


Agora vamos pegar um exemplo bem simples já com JavaScript:

const fn = ( x ) => !( x % 2 )

Com certeza você já deve saber para que serve essa função né???


Ótimo! Então vamos analisar sua assinatura:

Number -> Boolean



Vou explicar melhor então.

Qual o TIPO do argumento que a função recebe?

- Sei lá! Tem soh um x nesse negócio.

Pois bem, primeiramente devemos saber que essa função irá TESTAR se o número que entrar é PAR, se você não tinha entendido ainda melhor estudar mais JS hein!

Ok! Entra um Number e o retorno dessa função será true ou false, logo o tipo do retorno é: Boolean!


Ficou claro agora essa, Number -> Boolean, assinatura?


Pois bem, como sabemos o JS é fraca e dinamicamente tipado, ou seja, tamo fudido!


Como eu vivo estudando um pouquinho de Funcional sempre me deparo com essas assinaturas, um exemplo bem claro disso é o FantasyLand, veja comigo como é a assinatura do método equals:


equals :: Setoid a => a ~> a -> Boolean

E isso me incentivou a querer usar essa forma de "descrever" uma função, por isso criamos um projetinho para testar essas assinaturas de forma bem simples.


Por exemplo:

const test = require('./testSignature')

const { fn, signature } = require('./actions/isEven')

console.log('test: ', test(signature, [4], fn))

Para que isso funcione precisamos modularizar as funções com esse padrão:
const fn = ( x ) => !( x % 2 )
const signature = `Number -> Boolean`

module.exports = { fn, signature }

**E pronto! **


O módulo que faz isso acontecer, ainda está em desevolvimento pois é uma Prova de Conceito, é esse aqui:

const TYPES = require( './types' )

const signature = ( anotattion ) => anotattion.split( ' -> ' )

const check = ( test, type ) => test( type )

const checkType = ( TYPES, typeIn ) => 
  ( type, i ) => check( TYPES[typeIn], type )

const checkThis = ( data, TYPES, typeIn ) => 
  data.map( checkType( TYPES, typeIn ) )

const checkSignature = ( anotattion = [], data = [], fn ) => {
  const [ typeIn, typeOut ] = signature( anotattion )
  const computed = fn( ...data )
  const _in = checkThis( data, TYPES, typeIn )
  const _out = checkThis( [computed], TYPES, typeOut )

  return { _in, _out }
}

module.exports = checkSignature

Exemplos

  • toString:
const fn = ( x ) => x.toString()
const signature = `* -> String`

module.exports = { fn, signature }
  • toDouble:
const fn = ( x ) => x * 2
const signature = `Number -> Number`

module.exports = { fn, signature }
  • sum:
const sum = ( acc, cur ) => acc + cur

const fn = ( arr ) => arr.reduce( sum )
const signature = `Array -> Number`

module.exports = { fn, signature }

Embasamento Teórico

About

Teste via assinatura da funcão


Languages

Language:JavaScript 100.0%