If you're not French and plan to never write in French, you can just do
\documentclass{article}
\usepackage{amsmath}
\makeatletter
\mathchardef\normalcolon=\mathcode`:
\def\colon{%
\noexpand\nobreak
\mskip 2mu
\mathpunct{}
\nonscript\mkern -\thinmuskip
{\normalcolon}%
\mskip 6muplus1mu
\relax
}
\begingroup\lccode`\~=`\:\lowercase{\endgroup\let~}\colon
\mathcode`\:=\string"8000
\makeatother
\begin{document}
$f: A \to B$
$a\normalcolon b$
\end{document}
This would send TeX into infinite loop if babel-french
is used. A safer patch:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\usepackage{amsmath}
\makeatletter
\mathchardef\normalcolon=\mathcode`:
\def\colon{%
\noexpand\nobreak
\mskip 2mu
\mathpunct{}
\nonscript\mkern -\thinmuskip
{\normalcolon}%
\mskip 6muplus1mu
\relax
}
\@ifpackagewith{babel}{french}{% french babel makes : active
\declare@shorthand{french}{:}{%
\ifmmode % <--- added
\colon % <--- added
\else % <--- added
\ifFB@spacing
\ifhmode
\ifdim\lastskip>1sp
\unskip\penalty\@M\FBcolonspace
\else
\FDP@colonspace
\fi
\fi
\fi
\string:%
\fi % <--- added
}%
}{%
\begingroup\lccode`\~=`\:\lowercase{\endgroup\let~}\colon
\mathcode`\:=\string"8000
}
\makeatother
\begin{document}
$f: A \to B$
$a\normalcolon b$
\end{document}

You can still use \colon
with the standard meaning. For the colon as relation symbol (what you get normally in TeX with :
) I provided \normalcolon
.
Disclaimer. This doesn't work with XeLaTeX or LuaLaTeX.