Bueno,
afortunadamente en programación funcional las cosas son muy lineales.
Tenemos:
f :: [a] -> [b] -> a -> b
y tenemos otra función cuya implementación es:
g x = f x x
Si observamos la función, el lado derecho, vemos que f se aplica a 2 veces x. Por ende las "x" van a ir a parar al primer argumento de f y al segundo argumento de f.
El primer argumento de f es de tipo [a] y el segundo es de tipo de [b]
Como x está ahí no nos queda más que imaginar que x es una lista y que para este caso el tipo "a" es igual al tipo "b". Recordemos que esas letras: [a] y [b] indican que "potencialmente" podrían ser de tipos distintos, pero nada dicen de que no puedan ser el mismo tipo. Por ende como ambos reciben a "x" entonces x es una lista, porque machea con [a] y [b] y luego los tipos a y b son iguales.
¿Pero qué tipo son "a" y "b" entonces? No lo sabemos... sólo sabemos que son del mismo tipo. Para abreviar digamos que son de tipo "c" y veamos como quedaria:
f :: [c] -> [c] -> c -> c
y como g x = f x x, al aplicar los primeros dos parámetros de "f" nos queda una función así:
f x x :: c -> c
Pero bien, si f x x tiene tipo c -> c, entonces ¿qué tipo tiene "g"?
"g" toma un x por parámetro para dar como resultado una función de c -> c, por lo tanto podemos escribir que:
g :: x -> c -> c
g x = f x x
Espero me haya explicado bien, un saludo!